This document summarizes the evolution of Akeneo, an open source PHP product information management (PIM) software. It describes how Akeneo started as a small project in 2013 and has grown to have over 40 employees and 134k lines of code. It discusses challenges faced with scaling the codebase and team as new features and customers were added. The document emphasizes techniques used such as Agile methodologies, continuous integration, semantic versioning, and maintaining backwards compatibility to help scale the project in a sustainable way.
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Edition of an enterprise software in PHP, feedback
1. Edition of an Enterprise Software in PHP
NICOLAS DUPONT @duponico #forumphp joind.in/15714
2. NICOLAS DUPONT
Co-founder & Lead Developer
@duponico
nidup
agile software dev, continuous
improvement, open source, beers.
3. ENTERPRISE SOFTWARE
Solves an enterprise-wide problem
Improves the productivity
Is robust and reliable
For instance, Enterprise Resource Planning (ERP), Business Intelligence (BI), Customer
Relationship Management (CRM), Business Process Management (BPM), Master Data
Management (MDM), etc
5. COMMUNITY & ENTERPRISE EDITIONS
Symfony 2.7 Full Stack
+ Community Bundles
Open Source license, free of charge
Symfony 2.7 Full Stack
+ Community Bundles
+ Enterprise Bundles
+ SLA-backed support
Commercial license, annual subscription fee
25k+ installations
134k LoC (PHP)
60+ customers
134k LoC + 49k LoC (PHP)
8. KICK OFF
Timeline [01/13] ... 06/13 ...
Akeneo Team 4
Product Team 2
Community Edition starting (0 LoC)
Enterprise Edition not started
9. WHY PHP?
Strong community
Open source friendly
Good libraries (ex: thephpleague)
More and more mature (ex: composer)
Easy to hire for our partners
10. WHY SYMFONY (FULL STACK)?
Proven Framework
Strong community
Good documentation
Guidelines/practises
Speed up the development
11. BUSINESS APPLICATION NEEDS
UI (navigation, grid, etc)
User
Security
Workflow
Reporting
...
Common requirements
Same needs than OroCRM
Let's contribute to
12. FIRST DIFFICULTIES
Few months later...
Lot of technical pieces started...
Nothing 100% finished,
Nothing 100% useable
13. NEW ORGANIZATION!
Product owner joins the team
Scrum team (2 weeks / sprint)
Focus on business value
Focus on finished increments
Focus on technical practises
15. ALPHA RELEASE!
Timeline 01/13 ... [06/13] ... 01/14 ...
Akeneo Team 7 (+3)
Product Team 5 (+3)
Community Edition v1.0.0-alpha (39k LoC)
Enterprise Edition not started
16. FIRST PROJECTS
We integrate a first project on v1.0.0-alpha
Solution partners integrate few others
Integration? standard distrib, write custom import and export, add
extra models, write specific business rules, create new screens, etc
Problems! extensibility, unclear naming, lake of interfaces, too
much responsibilities per class, etc
17. CUSTOMIZABLE+MAINTAINABLE
SOLID OOP principles
+ Dependency Injection Container
+ Unit Tests
+ Functional Tests
= Easy to change any small part of the app
PhpMetric, size = Complexity,
color = Maintainability
pim_catalog.updater.product_property_setter:
class: %pim_catalog.updater.product_property_setter.class%
arguments:
'@pim_catalog.repository.cached_attribute'
'@pim_catalog.updater.setter.registry'
18. UNIT TESTS
1) Describe a class behavior
2) Implement the behavior
3) Refactor the code
>> Helps to specify and design classes
Today, ~1000 specs
class ProductBuilderSpec extends ObjectBehavior
{//[...]
function it_creates_product_without_family($repository, AttributeInterface $sku)
{
$repository>getIdentifier()>willReturn($sku);
$this>createProduct()>shouldReturnAnInstanceOf(self::PRODUCT_CLASS);
}//[...]
19. FUNCTIONAL TESTS
1) Describe a feature
2) Implement it
>> Helps to specify features
today, ~1400 scenarios
Feature: Edit a product
[...]
Scenario: Successfully edit and save a product
Given I am logged in as "Mary"
And I am on the "sandal" product page
And I fill in the following information:
| Name | My Sandal |
When I press the "Save" button
Then I should be on the product "sandal" page
And the product Name should be "My Sandal"
20. CONTINUOUS INTEGRATION
Jenkins CI
Static analysis (phpmd, phpcs, phpcpd, jshint, etc)
Unit Tests (phpspec, jasmine)
Functional + API Tests (behat) Jenkins CI
Travis CI
Static analysis + Unit Tests
Github Integration Travis CI
21. CODE WORKFLOW (GIT)
For each story / bug,
Create a new branch
Write code + tests
Do a pull request
Check the Definition Of Done (DOD)
Merge
Definition Of Done (Story)
| Q | A
| |
| Specs |
| Behats |
| Blue CI |
| Changelog updated |
| Code review and 2 GTM |
| Micro Demo (PO) |
| Migration script |
| Tech Doc |
22. STABLE RELEASE!
Timeline ... 06/13 ... [01/14] ... 04/14 ...
Akeneo Team 9 (+2)
Product Team 5 (=)
Community Edition v1.0.0 (62k LoC)
Enterprise Edition not started
23. COMMUNITY EDITION V1.0.0
Hard to release the first stable version
Why? very last change, postpone, another one, etc
So? ~2 months to "finish"
Lot of new projects (and problems)!
"If you are not embarrassed by the first version of your product, you’ve launched too late."
Reid Hoffman
24. PERFORMANCE PROBLEM
Customer with 100k products, 100 attributes
Application is slow (grids, forms)...
Why? Doctrine ORM hydration + greedy algo
So? ~1 month to optimize the code
25. SCALABILITY PROBLEM
Customer with 1M+ products
Application will not work...
Why? RDBMS + Entity Attribute Value (EAV)
So? ~1 month to add a MongoDB storage + minor release
26. LET'S START THE ENTERPRISE EDITION!
Timeline ... 01/14 ... [04/14] ... 11/14 ...
Akeneo Team 12 (+3)
Product Team 5 (=)
Community Edition v1.1.0 (67k LoC)
Enterprise Edition starting
27. NOT STARTED, ALREADY LATE!
Scope (~fixed): too big!
Team (fixed): 4 (+1) developers
Schedule (fixed): July, 3 months
Iron Triangle
28. ENTERPRISE EDITION V1.0.0
Extends the Community Edition
Brings workflow, advanced permissions, advanced versioning
Released 1 month late
By reducing scope (simplify and remove features)
By reducing internal quality (technical shortcuts)
29. NEW ACTIVITY
Support + Maintainance
3 minor versions (1.5 year)
Dedicated person / sprint
Qualify issues
Fix bugs (with new tests)
Release patches
30. TECHNICAL DEBT
Monetary debt metaphor
Not necessarily a bad thing
Must be managed
Must be paid back
Technical Debt Quadrant, Martin Fowler
31. TAKE CARE OF THE CODEBASE
Broken windows theory
Criminological theory (1982)
Prevent small crimes to avoid
more serious crimes
Boy scout rule
"Always leave the campground
code cleaner than you found it."
32. SCALE THE TEAM!
Timeline ... 04/14 ... [11/14] ... today
Akeneo Team 18 (+6)
Product Team 5 (=)
Community Edition v1.2.0 (78k LoC)
Enterprise Edition v1.0.0 (20k LoC)
33. PRODUCT TEAM SIZE X 3
Akeneo raises $2.4 Million and hiring time!
November + 2, December + 2, January + 2, February +2 ... Stop!
From 5 to 14 people in few months
Impacts on organization and architecture
34. SCALE THE ORGANIZATION
Squad: pluridisciplinary, autonomous, temporary, has a clear goal
Feature Squad x 3: Delivers finished product increments
Support/Maintainance Squad x 1: Takes care of our ecosystem
Tooling Squad x 1: Takes care of our tools (CI first)
35. SCALE THE ARCHITECTURE
Quite "monolithic software" is ok for a small team
Team size x 3 ~= features x 3 + side effects x 3 + dependencies x 3
Improve the internal API: querying, data update, validation, etc
Build new features by using this internal API
36. COUPLING, BUSINESS CODE - ORM
Business code directly uses Doctrine ORM classes
For performance reason, we need to write a direct to DB import
So? Introduce and use new interfaces!
namespace AkeneoComponentStorageUtilsSaver;
interface SaverInterface
{
public function save($object, array $options = []);
}
// RemoverInterface, ProductRepositoryInterface, AttributeRepositoryInterface, etc
37. COUPLING, BUSINESS CODE - FRAMEWORK
Business code directly uses Symfony Framework classes
In v1.0, product draft edition is coupled to Symfony Form
In v1.4, we need to import product drafts from csv files...
No way to re-use our business code... re-write a decoupled API
38. BACKWARD COMPATIBILITY
Semantic Versioning (semver.org)
Given a version vMAJOR.MINOR.PATCH
MAJOR+1 when you make incompatible API changes
MINOR+1 when you add functionality in a BC manner
PATCH+1 when you make BC bug fixes
Public API?
Software using Semantic Versioning MUST declare a public API
API could be declared in the code itself or exist strictly in doc
39. PUBLIC API
Symfony (since v2.3)
Declared in the code (interfaces and @api tag)
Explained in the doc with "Backwards Compatibility Promise"
Akeneo PIM (in v1.4)
Not declared... so, public API = 1500 classes and 6749 methods
We're working on a first declaration: CSV file formats for
imports/exports, connector interfaces and services, internal API,
etc
40. BC BREAK
Minor version (v1.4.0)
Add new features
Use of @deprecated tag for "API" changes
BC Break on "internal" code only
Upgrade doc and scripts
Patch version (v1.4.1)
Bugs fixes only
No BC Break (at all) on "API" and "internal"
41. DEPRECATED
Ex: import system has been revamped in v1.4
New system is introduced
Old system is deprecated (code and tests are kept)
Old system is maintained (tests are runned, bugs are fixed)
42. TODAY
Timeline ... 11/14 ... [today] ...
Akeneo Team 42 (+22)
Product Team 15 (+10)
Community Edition v1.4.0 (134k LoC)
Enterprise Edition v1.4.0 (50k LoC)
43. WHAT'S NEXT?
Improve User eXperience (productivity, perfs, etc)
Improve Developer eXperience (api, doc, support, etc)
Conquer the (PIM) world!