Code Impact

Product progress

Updated 10 Oct 2026, 6:45 am IST. This page refreshes every minute. The percentage counts roadmap capabilities. The screen list further down is the locked product surface list, and most of those screens are not queued yet.

27%of the product plan is done
20 done 2 in review 3 in progress 1 queued 1 blocked 46 not started 73 capabilities

Work queue: 41 done, 2 in review, 3 in progress, 9 queued, 1 blocked, 56 tasks.

Happening now

In progressAP-0036

Lead task outbox MySQL integration

Integration tests · queue step implement

builder is still writing the branch · autopilot/ap-0036

  • docs/modules/crm/lead-tasks.md Tests section names this Testcontainers file
  • createLeadTaskFor commits one open task, one crm.task_created audit row, one finished idempotency row, and one crm.task_due version 1 outbox row
  • The outbox payload is taskId, leadId, and dueAt, and the lead version_no is unchanged
  • A replay returns the same task and does not insert a second task, audit row, or outbox row
  • A different body returns idempotency_conflict
  • An unknown assignee rolls back the task, the audit row, the outbox row, and the idempotency row
  • No worker, inbox, or production behavior changes unless a failing test proves a bug
In progressAP-0040

Admin lead activity timeline

Admin screens · queue step implement

builder is still writing the branch · autopilot/ap-0040

  • docs/modules/crm/admin-lead-activities.md exists and names listLeadActivities and createLeadActivity
  • The timeline calls those client methods through the BFF, with CSRF and Idempotency-Key on create
  • activityType is only call, message, meeting, note, or demo, and occurredAt is UTC ending in Z
  • Empty, validation, conflict, and forbidden states are text
  • Vitest covers the empty timeline and the activity types, and apps/api is unchanged
In progressAP-0045

Staff curriculum entry route create and list

Curriculum · queue step implement · milestone CUR-04

builder is still writing the branch · autopilot/ap-0045

  • docs/modules/curriculum/entry-routes.md exists before the code and names listEntryRoutes and createEntryRoute
  • A curriculum-owned migration creates only cur_entry_routes, with the generated track_version_scope unique across program version, track version, and code
  • createEntryRoute requires curriculum.manage, stores status active, and a parent version that is not draft returns 409
  • An unknown version is 404, a learner receives 403 without the version being loaded, and a success appends one curriculum.entry_route_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the two entry-route operations
In reviewAP-0048

Staff number sequence list and allocation

Platform · queue step validate · milestone P1-01b

Pull request #16 · checks not passed yet · autopilot/ap-0048

  • docs/modules/system/number-sequences.md exists before the code and names listNumberSequences plus the internal ensure and allocate services
  • A new ADR and a system-owned migration create only sys_number_sequences and insert no sequence rows
  • listNumberSequences requires system.config.read and does not change next_value
  • allocateHumanNumber locks the row, returns the prefixed padded number, advances next_value by one, and does not insert a missing sequence
  • OpenAPI lists listNumberSequences and the slice adds no HTTP create or increment
In reviewAP-0052

Staff promotion update

Commerce · queue step validate · milestone P1-25

Pull request #18 · checks not passed yet · autopilot/ap-0052

  • docs/modules/commerce/promotion-update.md exists before the code and names updatePromotion
  • updatePromotion requires commerce.promotions.manage and If-Match, and a learner receives 403 without the promotion being loaded
  • The body cannot change code, status, or conditions, and a replaced discount still follows the ADR-0013 percentage or INR fixed rules
  • A real change bumps version_no and appends one commerce.promotion_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updatePromotion

Phase 0

9 of 10 done

Repository, database, login, API, worker, design shells, and a proven backup. Later phases build on this.

DoneM0.1

Repository boots cleanly

A clean clone installs, lints, typechecks, tests, and builds.

No task has been queued for this yet.

DoneM0.2

Compose foundation on loopback

MySQL, Redis, Keycloak, the API, the worker, and the three web shells start on loopback.

No task has been queued for this yet.

DoneM0.3

Empty database migrates

An empty database migrates the foundation tables.

No task has been queued for this yet.

DoneM0.4

API health, logging, and tracing

Health checks, structured logs, tracing, and problem responses.

1 task

DoneAP-0003

M0.4 part 2 tracing

queue step validate · milestone M0.4

commit 18fd451

  • OpenTelemetry and Sentry are wired through configuration
  • A missing DSN or endpoint disables export and does not crash boot
  • No DSN, token, or secret is committed
DoneM0.5

Keycloak login resolves to a person

A Keycloak login resolves to a person record.

No task has been queued for this yet.

DoneM0.6

Sample protected endpoint

A protected sample endpoint allows one caller and denies another.

No task has been queued for this yet.

DoneM0.7

OpenAPI client and admin sign-in

The generated API client calls that endpoint from the admin sign-in shell.

No task has been queued for this yet.

DoneM0.8

Worker, Redis, and outbox consumer

The worker consumes one outbox event exactly once.

1 task

DoneAP-0002

M0.8 worker outbox consumer

queue step validate · milestone M0.8

commit 67a3df0

  • A module spec exists at docs/modules/platform/worker-outbox.md before the code
  • apps/api and apps/worker import a shared package and do not import each other (D-0042)
  • The worker claims an unpublished identity.person_linked v1 row, records one inbox row, and marks the outbox row published
  • A second delivery of the same event does not create a second inbox row
  • No provider call, no schema change beyond the existing ops_outbox_events and ops_event_inbox tables, and no deploy
DoneM0.9

Design-system shells

Design tokens and the public, portal, admin, and mobile shells.

1 task

DoneAP-0004

M0.9 design-system shells

queue step validate · milestone M0.9

commit 330a6a0

  • packages/design-tokens exposes the approved token v1 values
  • web shells use those tokens and do not hard-code brand hex
  • White text and white icons are not used on Impact Orange #FF6A00 (D-0027)
BlockedM0.10

Backup and restore proven

An encrypted off-host backup can be restored. This step stays manual.

1 task

BlockedAP-0005

M0.10 backup and restore

queue step implement · milestone M0.10

Blocked: Restore drills stay manual. The autopilot must not dump or restore the live database.

  • A backup and a restore are proven on an isolated ci-test database
  • The live codeimpact_v2 database is not overwritten

Phase 1

10 of 23 done

A person can become a lead, get admitted and enrolled, be invoiced, pay, join a cohort, and be marked present.

In reviewP1-01

Reference data (holidays, sequences, settings, flags)

Holidays, number sequences, settings, and feature flags. No legal entity or campus data.

4 tasks

In reviewAP-0048

Staff number sequence list and allocation

Platform · queue step validate · milestone P1-01b

Pull request #16 · checks not passed yet · autopilot/ap-0048

  • docs/modules/system/number-sequences.md exists before the code and names listNumberSequences plus the internal ensure and allocate services
  • A new ADR and a system-owned migration create only sys_number_sequences and insert no sequence rows
  • listNumberSequences requires system.config.read and does not change next_value
  • allocateHumanNumber locks the row, returns the prefixed padded number, advances next_value by one, and does not insert a missing sequence
  • OpenAPI lists listNumberSequences and the slice adds no HTTP create or increment
QueuedAP-0049

Staff settings read and put

queue step implement · milestone P1-01c

  • docs/modules/system/settings.md exists before the code and names listSettings, getSetting, and putSetting
  • A new ADR and a system-owned migration create only sys_settings, with one global row per key and is_secret false
  • putSetting accepts only platform.timezone Asia/Kolkata and platform.currency INR
  • An update requires If-Match, a missing header is 428, a stale tag is 412, and a real change appends one audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three setting operations
QueuedAP-0050

Staff feature flag create and list

queue step implement · milestone P1-01d

  • docs/modules/system/feature-flags.md exists before the code and names listFeatureFlags and createFeatureFlag
  • No new migration is added; createFeatureFlag uses the existing sys_feature_flags table
  • createFeatureFlag requires features.manage, stores status active, and rejects a client status
  • A duplicate flag key returns 409 and a success appends one system.feature_flag_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the two feature-flag operations
DoneAP-0047

Staff holiday create and list

queue step validate · milestone P1-01a

commit 9b301b0

  • docs/modules/system/holidays.md exists before the code and names listHolidays and createHoliday
  • A new ADR and a system-owned migration create only sys_holidays, with campus_id null, no campus foreign key, and a database unique on global date and name
  • createHoliday requires system.calendar.manage, stores status active, and rejects campusId
  • A duplicate global date and name returns 409 and a success appends one system.holiday_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the two holiday operations
DoneP1-02a

Self profile

A signed-in person can read and update their own profile.

1 task

DoneAP-0006

Self profile update

queue step validate · milestone P1-02

commit c4c5644

  • docs/modules/identity/self-profile.md exists and names updateCurrentPerson
  • PATCH /me updates only the self-editable profile fields and increments version_no
  • A missing If-Match returns 428 and a stale If-Match returns 412
  • A successful update appends an audit event and does not change keycloak_subject or status
  • The OpenAPI document lists updateCurrentPerson and unit tests cover the forbidden and concurrency cases
DoneP1-02b

Person email addresses

A person can hold more than one email address.

1 task

DoneAP-0007

Current person email addresses

queue step validate · milestone P1-02b

commit ed875b4

  • docs/modules/identity/person-emails.md exists before the code
  • listCurrentEmails, addCurrentEmail, and removeCurrentEmail operate only on the signed-in person
  • A new email is stored unverified and no email provider is called
  • Exactly one primary email remains when the person has any email, and the last email cannot be removed
  • OpenAPI lists the three operationIds and unit tests cover a second person's denial
DoneP1-02c

Consent records

Consent is append-only.

1 task

DoneAP-0008

Append-only consent records

queue step validate · milestone P1-02c

commit 41a3e90

  • docs/modules/identity/consents.md exists before the code
  • A new identity-owned migration creates idn_consents and the applied migrations are unchanged
  • recordCurrentConsent appends a row, and a withdrawal is a new row rather than an update
  • The same Idempotency-Key replays and a different body returns 409 idempotency_conflict
  • OpenAPI lists listCurrentConsents and recordCurrentConsent, and unit tests cover replay and conflict
QueuedP1-02d

Relationships

Relationships and guardians.

1 task

QueuedAP-0051

Staff person relationship create and list

queue step implement · milestone P1-02d

  • docs/modules/identity/person-relationships.md exists before the code and names createPersonRelationship and listCurrentRelationships
  • A new ADR and an identity-owned migration create only idn_person_relationships, with restrict foreign keys to idn_people
  • createPersonRelationship requires relationships.manage, stores status active, and accepts only parent, guardian, spouse, and mentor
  • A self-link returns 422, a duplicate active triple returns 409, and a success appends one identity.relationship_created audit event
  • The self list returns only the caller's relationships, the same Idempotency-Key replays, and OpenAPI lists the two relationship operations
DoneP1-03

Role and assignment administration

Staff can create roles and scoped assignments.

1 task

DoneAP-0009

Role and assignment administration

queue step validate · milestone P1-03

commit c6db77a

  • docs/modules/authorization/role-administration.md exists before the code
  • createRole, getRole, and createRoleAssignment enforce authorization.manage or authorization.read as specified
  • super_admin succeeds and a learner, a campus-only grant, and a global deny are forbidden
  • Idempotent replay returns the original result and a changed body returns 409
  • Successful role creation and assignment append audit events, and OpenAPI lists the three operationIds
DoneP1-04

CRM lead slice

Create a lead, assign a counsellor, record activity and tasks, and move the stage.

6 tasks

DoneAP-0010

Staff lead create list and detail

queue step validate · milestone P1-04

commit 98c0ecf

  • docs/modules/crm/staff-leads.md exists before the code
  • A new crm-owned migration creates crm_leads and no campus, legal-entity, or catalogue table is added
  • createLead, listLeads, and getLead require crm.leads.create or crm.leads.read, and a learner receives 403
  • A created lead has status new, nullable campus and program ids, an audit event, and idempotent replay
  • OpenAPI lists the three operationIds and unit tests cover denial, replay, and idempotency conflict
DoneAP-0011

Staff lead counsellor assignment

queue step validate · milestone P1-05

commit 01262df

  • docs/modules/crm/lead-assignment.md exists before the code and names updateLead
  • A new crm-owned migration creates crm_lead_assignments and applied migrations are unchanged
  • updateLead with crm.leads.update sets owner_person_id, closes the open assignment, and appends one history row
  • A missing If-Match returns 428 and a stale If-Match returns 412
  • A learner receives 403 without the lead being loaded, OpenAPI lists updateLead, and unit tests cover denial, hidden existence, and a repeat assignment of the same owner
DoneAP-0012

Lead activity timeline

queue step validate · milestone P1-06

commit ddc5fe1

  • docs/modules/crm/lead-activities.md exists before the code
  • A new crm-owned migration creates crm_activities and no other crm table
  • createLeadActivity and listLeadActivities enforce crm.activities.create and crm.activities.read, and a learner receives 403
  • activity_type is only call, message, meeting, note, or demo, and the lead last_activity_at is updated in the same transaction
  • The same Idempotency-Key replays and a different body returns 409, and OpenAPI lists both operationIds
DoneAP-0013

Lead follow-up tasks

queue step validate · milestone P1-07

commit c436a6e

  • docs/modules/crm/lead-tasks.md exists before the code and an ADR sets the created task status to open
  • A new crm-owned migration creates crm_tasks and applied migrations are unchanged
  • createLeadTask and listLeadTasks enforce crm.tasks.create and crm.tasks.read, and a learner receives 403
  • A created task has status open, an existing assignee, an audit event, and idempotent replay
  • OpenAPI lists both operationIds and unit tests cover denial, hidden existence, replay, and conflict
DoneAP-0014

Lead task reminder job

queue step validate · milestone P1-08

commit 68063fb

  • docs/modules/crm/lead-task-reminder.md and an ADR name the internal event crm.task_due version 1
  • A successful createLeadTask writes one ops_outbox_events row in the same transaction, and a replay does not write another
  • The worker records one inbox row and marks the outbox row published
  • A second delivery of the same event does not create a second inbox row
  • No provider is called, no notification table is added, and no migration is added
DoneAP-0015

Lead stage transitions

queue step validate · milestone P1-09

commit 81ce899

  • docs/modules/crm/lead-stage.md exists before the code and names transitionLeadStage
  • Allowed lead edges follow Domain §42.1 and any other edge returns 422 invalid_state_transition
  • transitionLeadStage requires crm.leads.update, and a learner receives 403 without the lead being loaded
  • Entering lost stores lost_at and lost_reason_code, entering converted stores converted_at, and a success appends one audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists transitionLeadStage
DoneP1-05a

Catalogue categories

Catalogue categories.

1 task

DoneAP-0016

Staff catalogue categories

queue step validate · milestone P1-10

commit 10043f0

  • docs/modules/catalogue/categories.md and the next ADR exist before the code and name listCategories, createCategory, and updateCategory
  • A catalogue-owned migration creates only cat_categories, with created_at, updated_at, and version_no, and status has no CHECK
  • createCategory requires catalogue.manage, stores status active, and a duplicate code or slug returns 409 without finishing idempotency
  • updateCategory requires If-Match, a learner receives 403 without the row being loaded, and a real change appends one audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three category operations
DoneP1-05b

Catalogue programs

Catalogue programs.

1 task

DoneAP-0017

Staff catalogue programs

queue step validate · milestone P1-11

commit ee99c39

  • docs/modules/catalogue/programs.md exists before the code and names listPrograms, createProgram, and getProgram
  • A catalogue-owned migration creates only cat_programs, with a restrict foreign key to cat_categories and unique code and slug
  • createProgram requires catalogue.manage, stores status active and public_visibility private, and rejects any other programType
  • An unknown category is 404, a learner receives 403 without the program being loaded, and a success appends one audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three program operations
DoneP1-05c

Catalogue program update

Update a program without changing its code.

1 task

DoneAP-0018

Catalogue program update

queue step validate · milestone P1-12

commit 6e83365

  • docs/modules/catalogue/program-update.md exists before the code and names updateProgram
  • updateProgram requires catalogue.manage and If-Match, and a learner receives 403 without the program being loaded
  • The body cannot change code, status, categoryId, or public_visibility
  • A real change bumps version_no and appends one catalogue.program_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updateProgram
DoneP1-05d

Catalogue tracks

Tracks under a program.

1 task

DoneAP-0019

Staff catalogue tracks

queue step validate · milestone P1-13

commit 35a5dd2

  • docs/modules/catalogue/tracks.md exists before the code and names listProgramTracks, createProgramTrack, and updateTrack
  • A catalogue-owned migration creates only cat_tracks, with a restrict foreign key to cat_programs and uniqueness of code and slug within the program
  • createProgramTrack requires catalogue.manage, stores status active, and an unknown program returns 404
  • updateTrack requires If-Match, a learner receives 403 without the track being loaded, and a real change appends one audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three track operations
DoneP1-05e

Catalogue skills

Skills the catalogue can attach.

1 task

DoneAP-0020

Staff catalogue skills

queue step validate · milestone P1-14

commit ae80d45

  • docs/modules/catalogue/skills.md exists before the code and names listSkills, createSkill, and updateSkill
  • A catalogue-owned migration creates only cat_skills, with created_at, updated_at, and version_no, and category is not a foreign key
  • createSkill requires catalogue.manage, stores status active, and a duplicate skillKey or slug returns 409 without finishing idempotency
  • updateSkill requires If-Match, a learner receives 403 without the skill being loaded, and a real change appends one audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three skill operations
In reviewP1-06

Products, offers, prices, and payment plans

Products, offers, prices, payment plans, tax, promotions, and scholarships.

14 tasks

In reviewAP-0052

Staff promotion update

Commerce · queue step validate · milestone P1-25

Pull request #18 · checks not passed yet · autopilot/ap-0052

  • docs/modules/commerce/promotion-update.md exists before the code and names updatePromotion
  • updatePromotion requires commerce.promotions.manage and If-Match, and a learner receives 403 without the promotion being loaded
  • The body cannot change code, status, or conditions, and a replaced discount still follows the ADR-0013 percentage or INR fixed rules
  • A real change bumps version_no and appends one commerce.promotion_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updatePromotion
QueuedAP-0054

Staff scholarship program create and list

queue step implement · milestone P1-27

  • docs/modules/commerce/scholarship-programs.md exists before the code and names listScholarshipPrograms and createScholarshipProgram
  • A new ADR and a commerce-owned migration create only prd_scholarship_programs
  • createScholarshipProgram requires scholarships.manage, stores status active, and stores no amount and no GST rate
  • An authenticated learner can list active programs, and an anonymous caller receives 401 authentication_required
  • A duplicate code returns 409, a success appends one commerce.scholarship_program_created audit event, and OpenAPI lists both operations
QueuedAP-0055

Staff scholarship application create and list

queue step implement · milestone P1-28

  • docs/modules/commerce/scholarship-applications.md exists before the code and names listScholarshipApplications and createScholarshipApplication
  • A new ADR and a commerce-owned migration create only prd_scholarship_applications, with restrict foreign keys to prd_scholarship_programs and idn_people
  • A person can apply for themselves, another person's id without scholarships.manage is 403, and the stored status is submitted
  • The owner list returns only that person's rows, and global scholarships.read returns the queue
  • A success appends one commerce.scholarship_application_created audit event and OpenAPI lists both operations
QueuedAP-0056

Staff scholarship application decision

queue step implement · milestone P1-29

  • docs/modules/commerce/scholarship-decision.md exists before the code and names decideScholarshipApplication
  • A new ADR and a commerce-owned migration create only prd_scholarship_awards
  • decideScholarshipApplication requires scholarships.decide, and a learner receives 403 without the application being loaded
  • Approval from submitted writes one award and sets the application approved; rejection writes no award; any other status is 422 invalid_state_transition
  • The same Idempotency-Key replays one award at most, and OpenAPI lists decideScholarshipApplication
DoneAP-0021

Staff commercial product create list and detail

queue step validate · milestone P1-15

commit a47c1f6

  • docs/modules/commerce/products.md and the next ADR exist before the code and name listProducts, createProduct, and getProduct
  • A commerce-owned migration creates only prd_products and prd_product_programs, with restrict foreign keys to cat_programs and cat_tracks
  • createProduct requires commerce.catalogue.manage, stores status active and product_type program, and an unknown program returns 404
  • A learner receives 403 without the product being loaded, and a success appends one commerce.product_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three product operations
DoneAP-0022

Commercial product update

queue step validate · milestone P1-16

commit 5635508

  • docs/modules/commerce/product-update.md exists before the code and names updateProduct
  • updateProduct requires commerce.catalogue.manage and If-Match, and a learner receives 403 without the product being loaded
  • The body cannot change productCode, productType, status, programId, or trackId
  • A real change bumps version_no and appends one commerce.product_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updateProduct
DoneAP-0023

Staff commercial offer create list and detail

queue step validate · milestone P1-17

commit 21e6b31

  • docs/modules/commerce/offers.md exists before the code and names listOffers, createOffer, and getOffer
  • A commerce-owned migration creates only prd_offers, with a restrict foreign key to prd_products and entitlement_bundle_id nullable
  • createOffer requires commerce.offers.manage, stores status active, and rejects campusId, salesChannel, and entitlementBundleId
  • An unknown product is 404, a learner receives 403 without the offer being loaded, and a success appends one commerce.offer_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three offer operations
DoneAP-0024

Commercial offer update

queue step validate · milestone P1-18

commit 983f717

  • docs/modules/commerce/offer-update.md exists before the code and names updateOffer
  • updateOffer requires commerce.offers.manage and If-Match, and a learner receives 403 without the offer being loaded
  • The body cannot change code, productId, status, campusId, salesChannel, or entitlementBundleId
  • A real change bumps version_no and appends one commerce.offer_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updateOffer
DoneAP-0025

Staff offer price create and list

queue step validate · milestone P1-19

commit c23f288

  • docs/modules/commerce/offer-prices.md exists before the code and names listOfferPrices and createOfferPrice
  • A commerce-owned migration creates only prd_prices, with a restrict foreign key to prd_offers, DECIMAL(19,4) amount, and CHAR(3) currency_code
  • createOfferPrice requires commerce.pricing.manage, stores status active, and accepts only currency INR
  • An overlapping active price for the same offer and currency returns 409, and a success appends one commerce.price_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the two price operations
DoneAP-0026

Staff offer price update

queue step validate · milestone P1-20

commit 9f5ca54

  • docs/modules/commerce/price-update.md exists before the code and names updatePrice
  • updatePrice requires commerce.pricing.manage and If-Match, and a learner receives 403 without the price being loaded
  • The body cannot change offerId, status, or countryCode, and currency stays INR
  • A real change bumps version_no and appends one commerce.price_updated audit event; an overlapping active window returns 409
  • A stale If-Match returns 412 and OpenAPI lists updatePrice
DoneAP-0027

Staff payment plan create and list

queue step validate · milestone P1-21

commit e2ae7cc

  • docs/modules/commerce/payment-plans.md exists before the code and names listPaymentPlans and createPaymentPlan
  • A new ADR and a commerce-owned migration create only prd_payment_plans and prd_payment_plan_parts
  • createPaymentPlan requires commerce.pricing.manage, stores status active, and each part uses exactly one of percent or fixed amount
  • A duplicate code returns 409 and a success appends one commerce.payment_plan_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the two payment-plan operations
DoneAP-0028

Staff payment plan update

queue step validate · milestone P1-22

commit f831c6d

  • docs/modules/commerce/payment-plan-update.md exists before the code and names updatePaymentPlan
  • updatePaymentPlan requires commerce.pricing.manage and If-Match, and a learner receives 403 without the plan being loaded
  • The body cannot change code or status, and a replaced part still uses exactly one of percent or fixed amount
  • A real change bumps version_no and appends one commerce.payment_plan_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updatePaymentPlan
DoneAP-0029

Staff offer payment plan attach

queue step validate · milestone P1-23

commit c1d1507

  • docs/modules/commerce/offer-payment-plans.md exists before the code and names attachOfferPaymentPlan
  • A new ADR and a commerce-owned migration create only prd_offer_payment_plans, with restrict foreign keys to prd_offers and prd_payment_plans
  • attachOfferPaymentPlan requires commerce.pricing.manage, and a learner receives 403 without the offer or the plan being loaded
  • The first attach appends one commerce.offer_payment_plan_attached audit event, and a second attach of the same pair inserts neither a row nor an audit event
  • An unknown offer or an unknown plan returns 404 and OpenAPI lists attachOfferPaymentPlan
DoneAP-0030

Staff promotion create and list

queue step validate · milestone P1-24

commit 3ab9b24

  • docs/modules/commerce/promotions.md exists before the code and names listPromotions and createPromotion
  • A new ADR and a commerce-owned migration create only prd_promotions
  • createPromotion requires commerce.promotions.manage, stores status active, keeps a percentage as a normalized rate, and accepts only INR for a fixed discount
  • A duplicate code returns 409 and a success appends one commerce.promotion_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the two promotion operations
Not startedP1-07

Admissions

Applications, documents, and admission decisions.

No task has been queued for this yet.

Not startedP1-08

Enrollment, cohorts, and sessions

Enrollment, cohorts, timetable rules, and sessions.

No task has been queued for this yet.

Not startedP1-09

Orders, invoices, and payments

Orders, invoices, payment schedules, and receipts.

No task has been queued for this yet.

Not startedP1-10

Razorpay webhooks and reconciliation

Razorpay webhooks and reconciliation.

No task has been queued for this yet.

Not startedP1-11

Refunds and credit notes

Refunds and credit notes.

No task has been queued for this yet.

Not startedP1-12

Attendance

Student and staff attendance.

No task has been queued for this yet.

Not startedP1-13

Notifications

Templates, in-app notifications, and unwired email and WhatsApp adapters.

No task has been queued for this yet.

Not startedP1-14

Audit read models

Audit and operational read models.

No task has been queued for this yet.

In progressP1-UI

Staff admin screens

Admin screens for APIs that are already merged.

5 tasks

In progressAP-0040

Admin lead activity timeline

Admin screens · queue step implement

builder is still writing the branch · autopilot/ap-0040

  • docs/modules/crm/admin-lead-activities.md exists and names listLeadActivities and createLeadActivity
  • The timeline calls those client methods through the BFF, with CSRF and Idempotency-Key on create
  • activityType is only call, message, meeting, note, or demo, and occurredAt is UTC ending in Z
  • Empty, validation, conflict, and forbidden states are text
  • Vitest covers the empty timeline and the activity types, and apps/api is unchanged
QueuedAP-0041

Admin lead follow-up tasks

queue step implement

  • docs/modules/crm/admin-lead-tasks.md exists and names listLeadTasks and createLeadTask
  • The screen calls those client methods through the BFF, with CSRF and Idempotency-Key on create
  • The form does not send status and does not call updateCrmTask or a people directory
  • Empty, validation, not-found, and forbidden states are text
  • Vitest covers the empty list and the labels, and apps/api is unchanged
DoneAP-0037

Admin lead list and detail

queue step validate

commit 111da60

  • docs/modules/crm/admin-lead-list.md exists and the screens follow it
  • /leads calls listLeads and /leads/{leadId} calls getLead through the BFF session and packages/api-client
  • The access token is not rendered, and a signed-out visitor does not call the API
  • Loading, empty, forbidden, and unavailable states are text, and each lead has an accessible link name
  • Vitest markup tests cover those states, and apps/api, OpenAPI, and the generated client are unchanged
DoneAP-0038

Admin lead create form

queue step validate

commit 516fe9b

  • docs/modules/crm/admin-lead-create.md exists before the form
  • The form calls createLead with Idempotency-Key through the BFF and a CSRF check
  • The body omits status, personId, campusId, sourceId, and interestProgramId
  • validation_error, idempotency_conflict, forbidden, and success are visible as text, and submit cannot double-send
  • Vitest covers labels and those states, and apps/api is unchanged
DoneAP-0039

Admin lead counsellor assignment

queue step validate

commit 1a19cdf

  • docs/modules/crm/admin-lead-assignment.md exists and names updateLead
  • The form sends ownerPersonId, optional reason, and the lead versionNo through the BFF with CSRF
  • 412 stale_version offers a reload, and 404 says the lead or person was not found
  • The screen does not call listPeople or getPerson and does not send status or contact fields
  • Vitest covers the labels and those states, and apps/api is unchanged
In progressP1-QA

Database integration test coverage

MySQL integration tests for slices that are already merged.

5 tasks

In progressAP-0036

Lead task outbox MySQL integration

Integration tests · queue step implement

builder is still writing the branch · autopilot/ap-0036

  • docs/modules/crm/lead-tasks.md Tests section names this Testcontainers file
  • createLeadTaskFor commits one open task, one crm.task_created audit row, one finished idempotency row, and one crm.task_due version 1 outbox row
  • The outbox payload is taskId, leadId, and dueAt, and the lead version_no is unchanged
  • A replay returns the same task and does not insert a second task, audit row, or outbox row
  • A different body returns idempotency_conflict
  • An unknown assignee rolls back the task, the audit row, the outbox row, and the idempotency row
  • No worker, inbox, or production behavior changes unless a failing test proves a bug
DoneAP-0032

Consent append-only MySQL integration

queue step validate

commit d5c694b

  • docs/modules/identity/consents.md Tests section names this Testcontainers file
  • A grant and a later withdrawal are two idn_consents rows, and the grant row stays granted
  • The consent insert and its audit_events row commit together; a replay adds neither
  • A reused header with a different body returns idempotency_conflict and inserts nothing
  • A status outside granted and withdrawn is rejected by the CHECK constraint
  • No outbox row is written and no production behavior changes unless a failing test proves a bug
DoneAP-0033

Role key uniqueness MySQL integration

queue step validate

commit 09d7554

  • docs/modules/authorization/role-administration.md Tests section names this Testcontainers file
  • A duplicate role_key is rejected by MySQL and the failed create leaves no finished idempotency row
  • Replaying the same header and body returns the original role and does not insert a second role or audit row
  • A different body with the same header returns idempotency_conflict
  • An assignment to an unknown person rolls back; a global assignment commits one row and one audit row
  • No production behavior changes unless a failing test proves a bug
DoneAP-0034

Lead create transaction MySQL integration

queue step validate

commit 245ce71

  • docs/modules/crm/staff-leads.md Tests section names this Testcontainers file
  • createLeadFor commits one crm_leads row, one crm.lead_created audit row, and one finished idempotency row
  • A replay returns the same lead id and does not insert a second lead or audit row
  • A different body returns idempotency_conflict and leaves that one lead
  • An unknown personId rolls the lead, the audit row, and the idempotency row back
  • No outbox row is written and no production behavior changes unless a failing test proves a bug
DoneAP-0035

Lead assignment locking MySQL integration

queue step validate

commit 501dda9

  • docs/modules/crm/lead-assignment.md Tests section names this Testcontainers file
  • A real assignment bumps version_no and commits the lead, one open history row, and one crm.lead_assigned audit row
  • The same owner again does not bump version_no and writes no history or audit row
  • A stale If-Match returns stale_version and a missing If-Match returns precondition_required
  • After reassignment exactly one assignment has ends_at null
  • An unknown owner leaves the lead unchanged and no production behavior changes unless a failing test proves a bug

Phase 2

1 of 13 done

An enrolled learner gets a pinned curriculum, lessons, video, assessments, projects, and a verifiable certificate.

DoneP2-01

Program and track versions

Draft program versions and track versions.

3 tasks

DoneAP-0042

Staff program curriculum version create list and detail

queue step validate · milestone CUR-01

commit 7055d81

  • docs/modules/curriculum/program-versions.md and the next ADR exist before the code and name listProgramCurriculumVersions, createProgramCurriculumVersion, and getCurriculumVersion
  • A curriculum-owned migration creates only cur_program_versions, with a restrict foreign key to cat_programs, unique (program_id, version_number), and a status CHECK of draft, review, published, and retired
  • createProgramCurriculumVersion requires curriculum.manage, stores status draft, assigns the next version_number, and an unknown program returns 404
  • A learner receives 403 without the version being loaded, and a success appends one curriculum.program_version_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the three version operations
DoneAP-0043

Program curriculum version update

queue step validate · milestone CUR-02

commit 9d66214

  • docs/modules/curriculum/program-version-update.md exists before the code and names updateCurriculumVersion
  • updateCurriculumVersion requires curriculum.manage and If-Match, and a learner receives 403 without the version being loaded
  • The body cannot change versionNumber, status, programId, or the publication fields, and a version that is not draft returns 409
  • A real change bumps version_no and appends one curriculum.program_version_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updateCurriculumVersion
DoneAP-0044

Curriculum track versions on program version create

queue step validate · milestone CUR-03

commit 4557171

  • docs/modules/curriculum/track-versions.md exists before the code and adds no operationId
  • A curriculum-owned migration creates only cur_track_versions, with restrict foreign keys and unique (track_id, program_version_id, version_number)
  • createProgramCurriculumVersion writes one draft track version per catalogue track of the program in the same transaction
  • A program with no tracks writes none, and an idempotent replay does not insert track rows again
  • getCurriculumVersion includes those track versions, and OpenAPI still lists only the program-version operations
In progressP2-02

Entry routes and lessons

Entry routes on a draft program version. Lessons come after this.

2 tasks

In progressAP-0045

Staff curriculum entry route create and list

Curriculum · queue step implement · milestone CUR-04

builder is still writing the branch · autopilot/ap-0045

  • docs/modules/curriculum/entry-routes.md exists before the code and names listEntryRoutes and createEntryRoute
  • A curriculum-owned migration creates only cur_entry_routes, with the generated track_version_scope unique across program version, track version, and code
  • createEntryRoute requires curriculum.manage, stores status active, and a parent version that is not draft returns 409
  • An unknown version is 404, a learner receives 403 without the version being loaded, and a success appends one curriculum.entry_route_created audit event
  • The same Idempotency-Key replays, a different body returns 409, and OpenAPI lists the two entry-route operations
QueuedAP-0046

Curriculum entry route update

queue step implement · milestone CUR-05

  • docs/modules/curriculum/entry-route-update.md exists before the code and names updateEntryRoute
  • updateEntryRoute requires curriculum.manage and If-Match, and a learner receives 403 without the route being loaded
  • The body cannot change code or status, and a parent version that is not draft returns 409
  • A real change bumps version_no and appends one curriculum.entry_route_updated audit event; an unchanged patch does neither
  • A stale If-Match returns 412 and OpenAPI lists updateEntryRoute
Not startedP2-03

Publishing

Publishing a curriculum version so learners can be pinned to it.

No task has been queued for this yet.

Not startedP2-04

Entitlements

Entitlement grants and the access check.

No task has been queued for this yet.

Not startedP2-05

Journeys and progress

Learner journeys and progress.

No task has been queued for this yet.

Not startedP2-06

Files

Lesson files in object storage.

No task has been queued for this yet.

Not startedP2-07

Mux video

Video upload and playback authorization.

No task has been queued for this yet.

Not startedP2-08

Assessments

Assessments and the question bank.

No task has been queued for this yet.

Not startedP2-09

Projects and rubrics

Projects, rubrics, and reviews.

No task has been queued for this yet.

Not startedP2-10

Certificates

Certificates and public verification.

No task has been queued for this yet.

Not startedP2-11

Faculty delivery

Faculty delivery workflow.

No task has been queued for this yet.

Not startedP2-12

Learner web and mobile

Learner web and mobile.

No task has been queued for this yet.

Not startedP2-13

Notes and offline

Notes, bookmarks, and offline access.

No task has been queued for this yet.

Phase 3

0 of 10 done

Community: tips, challenges, spaces, moderation, reputation, mentorship, and events.

Not startedP3-01

IT Tips

No task has been queued for this yet.

Not startedP3-02

Challenges

No task has been queued for this yet.

Not startedP3-03

Spaces and posts

No task has been queued for this yet.

Not startedP3-04

Moderation

No task has been queued for this yet.

Not startedP3-05

Reputation

No task has been queued for this yet.

Not startedP3-06

Mentorship

No task has been queued for this yet.

Not startedP3-07

Events

No task has been queued for this yet.

Not startedP3-08

Search

No task has been queued for this yet.

Not startedP3-09

Realtime

No task has been queued for this yet.

Not startedP3-10

Recommendations

No task has been queued for this yet.

Phase 4

0 of 9 done

Career profile, jobs, membership, referrals, and a wallet that does not double-credit.

Not startedP4-01

Career profile

No task has been queued for this yet.

Not startedP4-02

Resume builder

No task has been queued for this yet.

Not startedP4-03

Employers

No task has been queued for this yet.

Not startedP4-04

Jobs

No task has been queued for this yet.

Not startedP4-05

Applications

No task has been queued for this yet.

Not startedP4-06

Membership

No task has been queued for this yet.

Not startedP4-07

Referrals

No task has been queued for this yet.

Not startedP4-08

Wallet

No task has been queued for this yet.

Not startedP4-09

Public profile consent

No task has been queued for this yet.

Phase 5

0 of 8 done

AI mentor, retrieval, coding runner, and autograding. Each part can be switched off on its own.

Not startedP5-01

AI Gateway

No task has been queued for this yet.

Not startedP5-02

AI Mentor

No task has been queued for this yet.

Not startedP5-03

Retrieval

No task has been queued for this yet.

Not startedP5-04

Resume and interview AI

No task has been queued for this yet.

Not startedP5-05

CodingRunner

No task has been queued for this yet.

Not startedP5-06

Autograding

No task has been queued for this yet.

Not startedP5-07

Mock interviews

No task has been queued for this yet.

Not startedP5-08

Recommendations

No task has been queued for this yet.

Tasks not on a roadmap line

QueuedAP-0053

Staff coupon create and list

queue step implement · milestone P1-26

  • docs/modules/commerce/coupons.md exists before the code and names listCoupons and createCoupon
  • A new ADR and a commerce-owned migration create only prd_coupons, with a restrict foreign key to prd_promotions
  • createCoupon requires commerce.promotions.manage, stores status active, and a duplicate code returns 409
  • A success appends one commerce.coupon_created audit event, and the same Idempotency-Key replays without a second row
  • OpenAPI lists listCoupons and createCoupon, and validateCoupon and prd_coupon_redemptions are absent

Pipeline checks

DoneAP-0001

Dry run heartbeat

queue step validate

commit fe858f7

  • tooling/autopilot/evidence/heartbeat.txt exists
  • the file contains exactly autopilot-dry-run-ok and a trailing newline
  • no other file changes
DoneAP-0031

Cloud builder dry run

queue step validate

commit 0e44fb4

  • tooling/autopilot/evidence/cloud-heartbeat.txt exists
  • the file contains exactly autopilot-cloud-dry-run-ok and one trailing newline
  • no other file changes

Screens still to build

Seven product surfaces are locked. Website, learner, and mobile screens are not being queued while their APIs are still being built. Admin screens are queued only for APIs already merged, and those tasks do not change the API. A row here moves to Queued, In progress, In review, or Done only when a real task is using it.

Marketing website

apps/web-public. Master §2.1. The app shell from M0.9 exists. A row changes when a task uses its id as the milestone.

StatusScreenWhere it sits
ShellApp shellPhase 0
Not startedProgram and track discoveryPhase 1, after catalogue is merged
Not startedSkill landing pagesAfter catalogue skills are merged
Not startedCareer pathsPhase 4
Not startedAdmissions and enquiriesPhase 1
Not startedCampus informationNeeds owner campus facts
Not startedEvents and workshopsPhase 3
Not startedFree resources and IT TipsPhase 3
Not startedInstructor profilesNo API queued yet
Not startedProject and learner showcasesPhase 2 and Phase 4
Not startedJobs and employer informationPhase 4
Not startedPublic certificate verificationPhase 2
Not startedPricing and payment entryPhase 1, after public offers exist
Not startedPublic support contentNo API queued yet
Not startedBlogs, FAQs, and SEO pagesNeeds the website CMS

Learner website

apps/web-portal. Master §2.2 and Appendix A, on the web. Phase 2 names “learner web” as one line. Each row is queued on its own after its API is merged.

StatusScreenWhere it sits
ShellApp shellPhase 0
Not startedToday and home dashboardPhase 2
Not startedSmart onboardingPhase 2
Not startedMy LearningPhase 2
Not startedLive learning and timetablePhase 1 cohorts, screen after the API
Not startedLesson experiencePhase 2
Not startedProtected and offline learningPhase 2
Not startedPractice and quizzesPhase 2
Not startedBrowser coding labPhase 5
Not startedAutogradingPhase 5
Not startedProjects and capstonesPhase 2
Not startedPortfolio and showcasePhase 4
Not startedAI Learning MentorPhase 5
Not startedAI academic-integrity controlsPhase 5
Not startedProgress and masteryPhase 2
Not startedIT Tips feedPhase 3
Not startedDaily and weekly challengesPhase 3
Not startedCommunity spacesPhase 3
Not startedPeer learningPhase 3
Not startedMentor access and doubtsPhase 3
Not startedEventsPhase 3
Not startedCareer centrePhase 4
Not startedAI mock interviewPhase 5
Not startedJobs and internshipsPhase 4
Not startedCredentialsPhase 2
Not startedAttendancePhase 1
Not startedDigital student IDNo API queued yet
Not startedFees and billingPhase 1
Not startedReferral programmePhase 4
Not startedWalletPhase 4
Not startedMembershipPhase 4
Not startedCalendarPhase 1
Not startedNotificationsPhase 1
Not startedBookmarks and notesPhase 2
Not startedSupportNo API queued yet
Not startedAccessibility and languageCross-cutting, no task yet
Not startedLow-bandwidth modeCross-cutting, no task yet

Learner Android and iOS

apps/mobile-learner. Same learner screens as the website, in the Android and iOS app. M0.9 is a shell with auth routing. Each screen is its own task after its API is merged.

StatusScreenWhere it sits
ShellApp shellPhase 0
Not startedToday and home dashboardPhase 2
Not startedSmart onboardingPhase 2
Not startedMy LearningPhase 2
Not startedLive learning and timetablePhase 1 cohorts, screen after the API
Not startedLesson experiencePhase 2
Not startedProtected and offline learningPhase 2
Not startedPractice and quizzesPhase 2
Not startedBrowser coding labPhase 5
Not startedAutogradingPhase 5
Not startedProjects and capstonesPhase 2
Not startedPortfolio and showcasePhase 4
Not startedAI Learning MentorPhase 5
Not startedAI academic-integrity controlsPhase 5
Not startedProgress and masteryPhase 2
Not startedIT Tips feedPhase 3
Not startedDaily and weekly challengesPhase 3
Not startedCommunity spacesPhase 3
Not startedPeer learningPhase 3
Not startedMentor access and doubtsPhase 3
Not startedEventsPhase 3
Not startedCareer centrePhase 4
Not startedAI mock interviewPhase 5
Not startedJobs and internshipsPhase 4
Not startedCredentialsPhase 2
Not startedAttendancePhase 1
Not startedDigital student IDNo API queued yet
Not startedFees and billingPhase 1
Not startedReferral programmePhase 4
Not startedWalletPhase 4
Not startedMembershipPhase 4
Not startedCalendarPhase 1
Not startedNotificationsPhase 1
Not startedBookmarks and notesPhase 2
Not startedSupportNo API queued yet
Not startedAccessibility and languageCross-cutting, no task yet
Not startedLow-bandwidth modeCross-cutting, no task yet

Team workspace and admin console

apps/web-admin. Master §2.3 and §2.4 share this app. Appendix B is the screen list. A row follows the tasks that name its id.

StatusScreenWhere it sits
ShellApp shell and sign-inPhase 0
DoneLead list, detail, and createPhase 1
In progressLead assignment, activity, and tasksPhase 1
Not startedExecutive dashboardNo API queued yet
Not startedCommunication timelinePhase 1
Not startedDemo and counsellingPhase 1
Not startedAdmissionsPhase 1
Not startedCohort and batch managementPhase 1
Not startedProgram and LMS managementPhase 2
Not startedReusable content graphPhase 2
Not startedContent libraryPhase 2
Not startedAssessment enginePhase 2
Not startedCoding administrationPhase 5
Not startedProjectsPhase 2
Not startedStudent managementPhase 1
Not startedAttendancePhase 1
Not startedFaculty managementPhase 2
Not startedFees and accounts receivablePhase 1
Not startedRefunds and credit notesPhase 1
Not startedExpenses and vendorsNo API queued yet
Not startedReconciliationPhase 1
Not startedReferral administrationPhase 4
Not startedWallet ledgerPhase 4
Not startedMembershipPhase 4
Not startedEventsPhase 3
Not startedCommunity administrationPhase 3
Not startedCareer and placementPhase 4
Not startedEmployer managementPhase 4
Not startedCertificate enginePhase 2
Not startedCommunications centrePhase 1 notifications
Not startedNotification automationPhase 1
Not startedHelpdeskNo API queued yet
Not startedWebsite CMSNo API queued yet
Not startedSEO managementNo API queued yet
Not startedHR and staff operationsNo API queued yet
Not startedRooms and assetsNo API queued yet
Not startedReports and BINo API queued yet
Not startedRisk and interventionNo API queued yet
Not startedImport and exportNo API queued yet
Not startedApproval workflowsNo API queued yet
Not startedAudit logPhase 1
Not startedSystem settingsPhase 1
Not startedFeature managementPhase 1
Not startedIntegrationsNo API queued yet

Team Android and iOS

apps/mobile-team. Master §2.3. One team app for faculty, mentors, counsellors, front desk, finance, placement, and campus work. The shell exists. Each role screen waits for its API.

StatusScreenWhere it sits
ShellApp shellPhase 0
Not startedRole-aware homePhase 1 operational admin
Not startedAdmissions counsellor workPhase 1
Not startedFaculty deliveryPhase 2
Not startedAttendance and front deskPhase 1
Not startedFinance and receiptsPhase 1
Not startedPlacement and career teamPhase 4
Not startedCommunity and supportPhase 3

Partner website

apps/web-portal. Master §2.5. Responsive web only, no partner mobile apps. Phase 4 mentions an employer portal as one line. Each page is queued after its API is merged.

StatusScreenWhere it sits
Not startedGuardian and parent viewsNo API queued yet
Not startedEmployer and recruiter portalPhase 4
Not startedCollege and corporate partnersNo API queued yet
Not startedCampus or centre operationsNot approved as a launch surface