Lewati ke isi

Spansa Migration and Cutover Plan

Operator reference for delivering spansa.gcgscola.id on the current dev stack while migrating school data from smpn1pmk.gcgscola.id.

Mode kerja: server
Workspace root: /home/scola/odoo
Docs read before implementation:
- scola-fe-v2/docs/ai-guidelines/development-guide.md
- scola-fe-v2/docs/ai-guidelines/workspace-governance.md
- scola-fe-v2/docs/ai-guidelines/architecture-api.md

1. Objective

Deliver a blue environment at spansa.gcgscola.id that uses the same code, module topology, schema family, and same-origin frontend architecture as dev.gcgscola.id, while migrating live school data from the legacy smpn1pmk.gcgscola.id instance.

After validation, the new stack takes over smpn1pmk.gcgscola.id as the canonical production hostname. spansa.gcgscola.id remains as a protected UAT/operator alias.

2. Audit Snapshot

Source production: smpn1pmk.gcgscola.id

  • Odoo config: /home/scola/odoo/odoo-smpn1pmk.conf
  • Database: scola_smpn1pmk
  • Port: 8072
  • Addons path: legacy custom_addons
  • Frontend root: /var/www/vue-app-pmk/dist
  • Public hosts:
  • smpn1pmk.gcgscola.id
  • be-smpn1pmk.gcgscola.id
  • Installed modules: 90
  • Public tables: 558
  • DB size: 2866 MB
  • Attachments: 22103
  • Stored files referenced: 21962
  • Active crons: 24

Dev baseline: dev.gcgscola.id

  • Odoo config: /home/scola/odoo/odoo-devscola.conf
  • Database: scoladev
  • Port: 8074
  • Addons path:
  • custom_addons_scola/openeducat
  • custom_addons_scola/opensource_modules
  • custom_addons_scola/gcgscola
  • Frontend root: /var/www/dev-scola/dist
  • Architecture: same-origin /api and /web
  • Installed modules: 167
  • Public tables: 982
  • Active crons: 54
  • scola_enabled_addon_skus already used as the tenant add-on source of truth

Existing smpn1pmk0 sandbox

  • Database: scola_smpn1pmk0
  • Partial uplift only
  • Not used as target base
  • Keep only as disposable reference if needed

3. Target Topology

Blue environment

  • Hostname: spansa.gcgscola.id
  • Database: scola_spansa
  • Odoo config: /home/scola/odoo/config/odoo-spansa.conf
  • Odoo service: odoo-spansa.service
  • Odoo port: 8078
  • Frontend root: /var/www/spansa/dist
  • Frontend code: scola-fe-v2 from develop
  • Backend code: custom_addons_scola/gcgscola from main

Runtime rules

  • Use same-origin frontend architecture, matching dev.gcgscola.id
  • Keep production VITE_API_URL unset
  • Nginx proxies:
  • /api/ -> http://127.0.0.1:8078
  • /web -> http://127.0.0.1:8078
  • Do not create a public be-spansa hostname for the new stack

Canonical hostname after cutover

  • Production hostname remains smpn1pmk.gcgscola.id
  • spansa.gcgscola.id stays available for operator/UAT access after go-live

4. Data Scope

Live-import scope

Migrate these into the live scola_spansa database:

  • identity and user graph: res_company, res_partner, res_users, role/group assignments
  • academic structure: academic years, terms, batches, classrooms, subjects, enrollments
  • teacher and student records
  • parent-facing records required by portal/session access
  • admission, report-card, discipline, counseling, library, LMS, and other school-operational data that still maps to active scola_* owners
  • ir_attachment
  • business documents and referenced filestore objects

Archive-only scope

Do not live-import large chatter history into the new production database. Archive it separately from the final source snapshot:

  • mail_followers
  • mail_followers_mail_message_subtype_rel
  • mail_message
  • mail_mail
  • mail_notification
  • mail_tracking_value
  • related discuss_* history that is not required by current runtime

5. Provisioning Contract

spansa is provisioned as a full-profile tenant using the current operator contract:

SC-LEARN,SC-ASSESS,SC-DAP,SC-LIB,SC-FIN,SC-OPS,SC-BOS,SC-STUDENT,SC-PEOPLE,SC-ATTEND+,SC-FOUND

Core remains the baseline install path via scola_bundle_core.

Recommended command:

cd /home/scola/odoo/custom_addons_scola/gcgscola

TARGET_PROFILE=full_profile_operator_ready \
TARGET_ADDON_SKUS="SC-LEARN,SC-ASSESS,SC-DAP,SC-LIB,SC-FIN,SC-OPS,SC-BOS,SC-STUDENT,SC-PEOPLE,SC-ATTEND+,SC-FOUND" \
TARGET_LICENSE_STATUS=active \
./scripts/upgrade_enterprise_tier.sh \
  scola_spansa \
  /home/scola/odoo/config/odoo-spansa.conf

6. Build and Rehearsal Sequence

6.1 Build blue stack

  1. Freeze FE and BE commit hashes.
  2. Create scola_spansa database and filestore.
  3. Create odoo-spansa config and service on port 8078.
  4. Build and deploy frontend to /var/www/spansa/dist.
  5. Configure nginx for spansa.gcgscola.id.
  6. Provision the database through the approved bundle/install path.

6.2 Migration toolkit

Create idempotent scripts under:

  • /home/scola/odoo/custom_addons_scola/gcgscola/scripts/migration/spansa/

Minimum operator artifacts:

  • source-to-target model mapping
  • row-count verification
  • sequence reset
  • attachment/filestore verification
  • archive export for chatter tables

6.3 Dry-runs

Run at least two full rehearsals:

  1. clone source DB
  2. provision clean scola_spansa
  3. run migration scripts
  4. record source vs target counts
  5. validate login and major role flows

Required parity checks:

  • users
  • partners
  • students
  • faculty
  • batches/classrooms
  • admissions
  • report-card entities
  • discipline/counseling entities
  • library entities
  • attachments and stored files

7. Cutover Runbook

Pre-cutover

  1. Announce freeze window.
  2. Confirm FE and BE artifacts match the approved commit hashes.
  3. Disable source crons that would create moving targets.
  4. Take final backups:
  5. PostgreSQL dump
  6. filestore snapshot
  7. archive snapshot for chatter/history

Final migration

  1. Stop source writes.
  2. Run final delta import into scola_spansa.
  3. Verify counts and critical business entities.
  4. Run smoke checks on spansa.gcgscola.id.

Go-live

  1. Switch smpn1pmk.gcgscola.id nginx to the new FE/BE stack.
  2. Keep spansa.gcgscola.id mapped to the same blue stack for UAT/operator verification.
  3. Keep legacy stack offline but recoverable during hypercare.

8. Validation Checklist

Technical

  • frontend uses /api and /web in same-origin mode
  • auth/session works without legacy cross-origin behavior
  • scola_enabled_addon_skus matches the approved full-profile contract
  • residual scola_* module states are empty after provisioning
  • attachments resolve correctly after filestore copy

Functional

  • admin login
  • teacher login
  • student login
  • parent login
  • counselor/discipline flows
  • library flows
  • admission/public pages
  • report-card views
  • attendance and timetable flows

Observability

  • Odoo service healthy on 8078
  • nginx serves /, /api/, and /web
  • no repeated feature_disabled for expected in-scope packages

9. Rollback

Rollback immediately if any of these fail:

  • login/session stability
  • missing critical school data
  • broken attachment/document access
  • blocked core workflow for active roles

Rollback steps:

  1. point smpn1pmk.gcgscola.id back to the legacy stack
  2. re-enable legacy crons if needed
  3. retain scola_spansa for forensic comparison
  4. restore from final pre-cutover snapshot if data repair is required

10. Notes

  • This plan assumes no changes to Odoo core or legacy custom_addons.
  • spansa is a migration/UAT delivery alias, not the long-term canonical public URL.
  • The operator should always pass the explicit full-profile add-on list for spansa, even if the default script profile later matches it.