Event-driven sync over scheduled batch
The first design had a scheduled batch sync — every 15 minutes, pull content from Odoo. Rejected. A teacher who publishes content should see it live immediately. We rebuilt the sync as event-driven: Odoo webhook triggers portal update.
Rationale: 15-minute lag between a teacher publishing and learners seeing the update is not acceptable in a live learning context. Event-driven sync eliminates this lag. Sync time went from up to 15 minutes to under 90 seconds.
Trade-off accepted: More complex webhook handling and error retry logic in exchange for near-real-time content delivery.
Completion-triggered certificate generation
Manual certificate generation was a support ticket trigger — learners completing a module and not receiving a certificate immediately would contact support. We built completion-triggered certificate generation. On module completion, certificate generates and delivers automatically. Zero manual steps.
Rationale: Every manual step in a completion workflow is a potential failure point. Automating certificate generation eliminates the most common support ticket category after launch.
Trade-off accepted: More complex completion state machine in exchange for zero support tickets for certificate delivery.
Odoo as source of truth
We made a deliberate architecture decision: Odoo owns the content data. The portal is read-only against Odoo. This means the educator's workflow does not change — they still work in Odoo — but the learner experience is built on top of it.
Rationale: Asking educators to learn a new content management tool would have created adoption resistance. Keeping Odoo as the editorial interface preserved their existing workflow while delivering a modern learner experience.
Trade-off accepted: Portal flexibility is constrained by Odoo's data model — accepted in exchange for zero workflow change for educators.