7b8f81336a
Build & Push / Pipeline Tests (push) Failing after 2m0s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 53s
Test / API Unit Tests (push) Successful in 1m8s
Test / Homepage Unit Tests (push) Successful in 48s
Test / Carplace Unit Tests (push) Successful in 42s
Test / Admin Unit Tests (push) Successful in 41s
Test / Dashboard Unit Tests (push) Successful in 43s
Test / API Integration Tests (push) Failing after 1m7s
509 lines
26 KiB
Markdown
509 lines
26 KiB
Markdown
# Subscription Upgrade Implementation Plan
|
||
|
||
## 1. Purpose
|
||
|
||
Implement a safe subscription-upgrade workflow for companies that already have an active plan and pay manually. The workflow must calculate a defensible upgrade amount, collect payment evidence, require platform-admin verification, activate the new plan without losing history, and communicate in the company's selected language: English (`en`), French (`fr`), or Arabic (`ar`).
|
||
|
||
## 2. Product Policy
|
||
|
||
### 2.1 Supported upgrade options
|
||
|
||
| Option | Billing treatment | Activation | Renewal date | Availability |
|
||
|---|---|---|---|---|
|
||
| Upgrade now — prorated | Charge the net price difference for the unused part of the current term | After payment verification | Unchanged | Primary self-service option |
|
||
| Upgrade at renewal | No immediate charge; schedule the new plan for the next term | At renewal | Existing renewal date | Secondary self-service option |
|
||
| Upgrade now — reset term | Credit eligible unused current-plan value and begin a full new term | After payment verification | Reset to activation date | Platform-admin assisted |
|
||
| Temporary add-on | Keep the current plan and charge for a defined feature or limit | After payment verification | Unchanged | Out of scope until add-on rules exist |
|
||
|
||
### 2.2 Mandatory rules
|
||
|
||
1. A company may upgrade only from an active or grace-period subscription to a higher eligible plan.
|
||
2. A submitted receipt is evidence, not proof of cleared payment.
|
||
3. Upgraded access is granted only after a platform admin verifies payment.
|
||
4. The existing subscription record and plan history must never be overwritten or deleted.
|
||
5. Only one non-terminal upgrade request may exist per subscription.
|
||
6. An issued quote is immutable. If it expires, create a new quote using current inputs.
|
||
7. Upgrades, renewals, downgrades, add-ons, and plan changes made by platform admins must use distinct actions and audit events.
|
||
8. A term reset requires explicit company confirmation because it changes the renewal date.
|
||
9. Only company billing contacts and company admins receive customer payment communications. Do not notify every company user.
|
||
10. All customer-facing communication uses the company's selected supported language. Arabic content must render in true RTL.
|
||
|
||
## 3. Scope
|
||
|
||
### In scope
|
||
|
||
- Immediate prorated upgrade.
|
||
- Upgrade scheduled for renewal.
|
||
- Manual payment instructions and receipt upload.
|
||
- Platform-admin review, approval, rejection, and request-for-correction actions.
|
||
- Plan-entitlement activation after verified payment.
|
||
- EN, FR, and AR user interfaces and notifications.
|
||
- Quote expiry, cancellation, audit history, idempotency, and reporting.
|
||
- Migration-safe data changes and automated/manual testing.
|
||
|
||
### Out of scope for the first release
|
||
|
||
- Automatic card or bank collection.
|
||
- Automatic refunds or cash credits.
|
||
- Downgrades.
|
||
- Temporary add-ons unless pricing, duration, renewal, and removal behavior are separately defined.
|
||
- Mid-upgrade currency changes.
|
||
- Self-service term resets.
|
||
- Changing the billing cadence during a standard prorated upgrade.
|
||
|
||
## 4. Roles and Permissions
|
||
|
||
| Action | Company user | Billing contact | Company admin | Platform admin |
|
||
|---|---:|---:|---:|---:|
|
||
| View current plan and available upgrades | Optional | Yes | Yes | Yes |
|
||
| Request an upgrade | No | Yes | Yes | Yes, on behalf of company |
|
||
| View quote and payment instructions | No | Yes | Yes | Yes |
|
||
| Upload or replace payment evidence | No | Yes | Yes | Yes |
|
||
| Cancel an unpaid request | No | Yes | Yes | Yes |
|
||
| Verify or reject payment | No | No | No | Yes |
|
||
| Activate an upgrade | No | No | No | System after verification |
|
||
| Override price, eligibility, or effective date | No | No | No | Separate privileged permission plus reason |
|
||
| View internal review notes | No | No | No | Yes |
|
||
|
||
Enforce permissions on the server. Hiding a control in the UI is not authorization.
|
||
|
||
## 5. Upgrade Eligibility
|
||
|
||
The eligibility service must check all of the following before showing or quoting a target plan:
|
||
|
||
- The subscription exists and belongs to the requesting company.
|
||
- Subscription status is `active` or an explicitly supported `grace_period` state.
|
||
- The target plan is active, sellable, and ranked above the current plan.
|
||
- Current and target plans use the same currency and billing cadence for the standard prorated path.
|
||
- The target plan supports the company's region and contractual conditions.
|
||
- No non-terminal upgrade request already exists.
|
||
- The subscription is not suspended for fraud, legal, or administrative reasons.
|
||
- There is enough time remaining to justify an immediate upgrade under the configured minimum-charge policy.
|
||
- Any company-specific contract or negotiated pricing is supported by the quote engine; otherwise route to platform-admin assistance.
|
||
|
||
Never infer that a more expensive plan is necessarily an upgrade. Use an explicit plan transition matrix or plan rank plus compatibility rules.
|
||
|
||
## 6. Pricing and Proration
|
||
|
||
### 6.1 Standard formula
|
||
|
||
Use day-based proration for a same-cadence immediate upgrade:
|
||
|
||
```text
|
||
term_days = renewal_date - term_start_date
|
||
remaining_days = renewal_date - effective_date
|
||
|
||
remaining_new_plan_value = target_net_term_price × remaining_days ÷ term_days
|
||
remaining_current_plan_credit = eligible_current_net_term_price × remaining_days ÷ term_days
|
||
|
||
upgrade_subtotal = max(0, remaining_new_plan_value - remaining_current_plan_credit)
|
||
upgrade_total = upgrade_subtotal + taxes + explicit_fees
|
||
```
|
||
|
||
For a current annual price of $1,200, a target annual price of $2,400, and exactly half the term remaining:
|
||
|
||
```text
|
||
($2,400 - $1,200) × 0.5 = $600
|
||
```
|
||
|
||
### 6.2 Pricing rules
|
||
|
||
- Store money as integer minor units and use a fixed decimal/rounding policy. Never use binary floating point for billing.
|
||
- Use the subscription's actual eligible net price, not merely the current public catalog price.
|
||
- Decide explicitly whether current-plan discounts carry to the new plan. Default: they do not carry unless contractually marked transferable.
|
||
- Calculate tax using the legally required point and method. Do not assume the simple price difference is tax-complete.
|
||
- Define whether the effective date is the quote date, payment-received date, or approval date. Recommended: approval timestamp, with the quote calculated through a clearly stated valid-until date and recalculated if expired.
|
||
- If partial-day precision is unnecessary, use the company's billing timezone and calendar dates consistently. Do not mix UTC timestamps with local-date proration.
|
||
- Set a minimum charge and rounding rule per currency. If the calculated charge is below the minimum, offer upgrade at renewal or allow a documented admin waiver.
|
||
- Store every pricing input and output in the quote snapshot so later catalog or tax changes cannot rewrite history.
|
||
|
||
### 6.3 Quote contents
|
||
|
||
Each quote must show and store:
|
||
|
||
- Current plan and target plan.
|
||
- Current term start and renewal date.
|
||
- Proposed activation method.
|
||
- Proration dates and fraction.
|
||
- Current-plan eligible credit.
|
||
- Target-plan remaining value.
|
||
- Discounts, taxes, fees, subtotal, and total.
|
||
- Currency and rounding result.
|
||
- Quote creation and expiry timestamps.
|
||
- Price-list, tax-rule, and calculation-version identifiers.
|
||
- Terms accepted by the requesting user.
|
||
|
||
## 7. State Model
|
||
|
||
### 7.1 Upgrade request states
|
||
|
||
| State | Meaning | Allowed next states |
|
||
|---|---|---|
|
||
| `draft` | Target plan selected; quote not submitted | `quoted`, `cancelled` |
|
||
| `quoted` | Immutable quote issued | `payment_pending`, `expired`, `cancelled` |
|
||
| `payment_pending` | Company accepted quote and received payment instructions | `payment_review`, `expired`, `cancelled` |
|
||
| `payment_review` | Evidence submitted for platform review | `correction_required`, `approved`, `rejected`, `expired` |
|
||
| `correction_required` | Evidence or payment details need correction | `payment_review`, `expired`, `cancelled` |
|
||
| `approved` | Payment verified and activation transaction authorized | `activated`, `activation_failed` |
|
||
| `activated` | New plan and entitlements are active | Terminal |
|
||
| `scheduled` | Upgrade is scheduled for renewal | `activated`, `cancelled`, `superseded` |
|
||
| `rejected` | Payment or request rejected | Terminal |
|
||
| `expired` | Quote/request validity elapsed | Terminal; requote creates a new request |
|
||
| `cancelled` | Cancelled before activation | Terminal |
|
||
| `activation_failed` | Payment approved but activation did not complete | `activated` through idempotent retry or manual incident resolution |
|
||
| `superseded` | Scheduled request replaced by a newer valid request | Terminal |
|
||
|
||
Do not encode upgrade progress as the primary subscription status. Keep the subscription active on its existing plan while the upgrade request is pending.
|
||
|
||
### 7.2 Transition controls
|
||
|
||
- Every transition must validate the current state to prevent stale or duplicate actions.
|
||
- Approval and activation must be idempotent.
|
||
- Only the activation transaction may change the active plan and entitlements.
|
||
- `approved` must not become `rejected`; use a reversal/incident process if an approval was mistaken.
|
||
- Scheduled upgrades must be revalidated before renewal activation.
|
||
|
||
## 8. Data Model
|
||
|
||
### 8.1 `subscription_upgrade_requests`
|
||
|
||
- `id`
|
||
- `company_id`
|
||
- `subscription_id`
|
||
- `request_type` (`immediate_prorated`, `at_renewal`, `term_reset`)
|
||
- `from_plan_id`, `from_plan_version_id`
|
||
- `to_plan_id`, `to_plan_version_id`
|
||
- `status`
|
||
- `requested_by_user_id`
|
||
- `requested_at`
|
||
- `effective_at`
|
||
- `scheduled_for`
|
||
- `quote_id`
|
||
- `company_language_snapshot`
|
||
- `billing_timezone_snapshot`
|
||
- `accepted_terms_version`
|
||
- `accepted_at`
|
||
- `cancelled_at`, `cancelled_by`, `cancellation_reason`
|
||
- `expires_at`
|
||
- optimistic-lock/version column
|
||
- created/updated timestamps
|
||
|
||
### 8.2 `subscription_upgrade_quotes`
|
||
|
||
- `id`, `upgrade_request_id`
|
||
- currency
|
||
- current eligible net term price
|
||
- target net term price
|
||
- term start, renewal date, pricing effective date
|
||
- term days, remaining days, proration numerator/denominator
|
||
- current credit, target remaining value
|
||
- discounts, taxes, fees, subtotal, total in minor units
|
||
- calculation version and serialized input snapshot
|
||
- created/expired timestamps
|
||
- immutable hash or integrity field if supported
|
||
|
||
### 8.3 Payment evidence and review
|
||
|
||
Reuse the existing manual-payment model when possible. It must relate evidence to the exact upgrade request and quote, and record:
|
||
|
||
- Evidence file metadata and secure storage reference.
|
||
- Amount claimed, currency, payment method, reference number, and claimed payment date.
|
||
- Uploader and upload time.
|
||
- Review status, reviewer, review time, internal notes, and rejection/correction reason.
|
||
- Verified amount and currency.
|
||
- Malware-scan status and access controls.
|
||
|
||
Do not store sensitive full bank-account or payment-card data in notes or uploaded filenames.
|
||
|
||
### 8.4 `subscription_plan_history`
|
||
|
||
- subscription, company, previous plan/version, new plan/version
|
||
- change type (`upgrade`)
|
||
- source upgrade request and approved payment references
|
||
- effective timestamp
|
||
- previous and new term dates
|
||
- actor and approving platform admin
|
||
- entitlement snapshot or version references
|
||
- audit correlation ID
|
||
|
||
### 8.5 Constraints and indexes
|
||
|
||
- Partial unique constraint: one non-terminal upgrade request per subscription.
|
||
- Unique activation key per upgrade request.
|
||
- Foreign keys to company, subscription, immutable plan versions, quote, and payment review.
|
||
- Indexes for company/status, subscription/status, expiry, scheduled activation, and admin review queue.
|
||
|
||
## 9. Backend Services and API
|
||
|
||
### 9.1 Services
|
||
|
||
- Eligibility service: returns permitted plan transitions and reasons for ineligibility.
|
||
- Quote service: calculates and freezes price snapshots.
|
||
- Upgrade workflow service: validates transitions and authorization.
|
||
- Manual-payment service: issues instructions and manages evidence/review.
|
||
- Activation service: atomically changes plan history, active plan/version, entitlements, and audit events.
|
||
- Notification service: selects recipients, language, template, and channel.
|
||
- Expiry/scheduling worker: expires quotes and activates renewal-scheduled upgrades safely.
|
||
|
||
### 9.2 Suggested endpoints
|
||
|
||
```text
|
||
GET /api/subscriptions/{id}/upgrade-options
|
||
POST /api/subscriptions/{id}/upgrade-quotes
|
||
POST /api/upgrade-requests/{id}/accept
|
||
POST /api/upgrade-requests/{id}/payment-evidence
|
||
POST /api/upgrade-requests/{id}/cancel
|
||
GET /api/upgrade-requests/{id}
|
||
|
||
GET /api/admin/upgrade-requests?status=payment_review
|
||
POST /api/admin/upgrade-requests/{id}/request-correction
|
||
POST /api/admin/upgrade-requests/{id}/approve-payment
|
||
POST /api/admin/upgrade-requests/{id}/reject-payment
|
||
POST /api/admin/upgrade-requests/{id}/retry-activation
|
||
```
|
||
|
||
Mutation endpoints must accept an idempotency key and reject stale version numbers.
|
||
|
||
### 9.3 Activation transaction
|
||
|
||
In one database transaction or equivalent consistency boundary:
|
||
|
||
1. Lock the upgrade request and subscription.
|
||
2. Confirm request state is `approved` and not already activated.
|
||
3. Recheck company/subscription ownership and target-plan validity.
|
||
4. Write the subscription plan-history record.
|
||
5. Set the active immutable plan version.
|
||
6. Apply new entitlements and limits.
|
||
7. Preserve or reset term dates according to the accepted request type.
|
||
8. Mark the request `activated`.
|
||
9. Write audit/outbox events.
|
||
|
||
Send notifications after commit through an outbox/queue. A failed email must not roll back an activated subscription.
|
||
|
||
## 10. User Experience
|
||
|
||
### 10.1 Company flow
|
||
|
||
1. Billing contact/admin opens Billing > Current plan.
|
||
2. System displays eligible higher plans and a comparison of entitlements and limits.
|
||
3. User selects `Upgrade now` or `Upgrade at renewal`.
|
||
4. System displays a transparent quote, effective-date policy, renewal-date effect, and expiry.
|
||
5. User accepts the upgrade terms.
|
||
6. For immediate upgrade, system displays localized manual-payment instructions.
|
||
7. User uploads payment evidence and can see review status.
|
||
8. Platform admin reviews payment.
|
||
9. After approval, the system activates the plan and displays confirmation, effective date, next renewal date, and new limits.
|
||
|
||
The confirmation screen must not imply immediate access before payment verification.
|
||
|
||
### 10.2 Platform-admin flow
|
||
|
||
- Review queue sorted by aging and quote expiry risk.
|
||
- Company, current/target plan, quote breakdown, claimed and expected payment, evidence, and previous attempts visible in one view.
|
||
- Actions: approve, request correction, reject, or open company/contact record.
|
||
- Approval requires confirmation of amount, currency, cleared-payment reference, and reviewer identity.
|
||
- Overrides require elevated permission and a mandatory reason.
|
||
- Approved-but-failed activations appear in a separate incident queue and must not invite a second approval.
|
||
|
||
### 10.3 Accessibility and responsiveness
|
||
|
||
- Keyboard-accessible comparison, forms, uploads, dialogs, and admin actions.
|
||
- Visible focus, descriptive validation, status announcements, and sufficient contrast.
|
||
- Do not encode status by color alone.
|
||
- Responsive layouts for company and admin flows.
|
||
- Currency, dates, and numbers formatted for the selected locale while stored canonically.
|
||
|
||
## 11. Localization and Notifications
|
||
|
||
### 11.1 Language selection
|
||
|
||
- Resolve the company's selected communication language at request creation and store a snapshot.
|
||
- Use only `en`, `fr`, or `ar`; define a deliberate fallback, recommended `en`, and log missing translations.
|
||
- Use company language for shared company communications. If future requirements demand per-recipient language, make that a separate policy decision.
|
||
- Arabic templates, PDFs, email layouts, and in-app screens must use RTL layout, not merely translated strings.
|
||
|
||
### 11.2 Notification events
|
||
|
||
| Event | Company billing contact/admin | Platform admin |
|
||
|---|---|---|
|
||
| Quote created | In-app + email | Optional in-app |
|
||
| Payment instructions issued | In-app + email | Optional in-app |
|
||
| Evidence submitted | In-app confirmation | In-app queue notification |
|
||
| Correction required | In-app + email | In-app status |
|
||
| Payment rejected | In-app + email | In-app status |
|
||
| Upgrade activated | In-app + email | In-app confirmation |
|
||
| Quote/request expiring soon | In-app + email | In-app for aging requests |
|
||
| Quote/request expired | In-app + email | In-app status |
|
||
| Activation failed after approval | Generic processing message only | Urgent in-app + operational alert |
|
||
|
||
Templates must include company name, current and target plans, amount/currency where appropriate, quote expiry, effective-date rule, renewal-date effect, and a safe deep link. Never attach raw payment evidence to email.
|
||
|
||
## 12. Limits and Entitlements
|
||
|
||
Define behavior for every entitlement before implementation:
|
||
|
||
- Higher quantitative limits become available only at activation.
|
||
- Feature flags follow the immutable target plan version.
|
||
- Existing usage is preserved.
|
||
- No destructive data migration may occur during an upgrade.
|
||
- Cache invalidation must occur immediately after commit.
|
||
- Active sessions must receive updated authorization without requiring an unsafe manual workaround.
|
||
- If entitlement propagation fails, mark activation as failed or partially failed according to a defined recovery policy; do not silently claim success.
|
||
|
||
## 13. Expiry, Cancellation, and Recovery
|
||
|
||
- Recommended quote validity: configurable, initially 7 calendar days, capped by renewal date.
|
||
- Send an expiry warning 48 hours before expiry when the request is still actionable.
|
||
- Expiry workers must be idempotent and must not expire an already approved request.
|
||
- Company cancellation is allowed only before approval/activation and does not delete history or evidence.
|
||
- Requoting creates a new request or quote version linked to the expired one; it never mutates the expired quote.
|
||
- A rejected payment cannot be reopened silently. Start a new review attempt or request according to the audit policy.
|
||
- Activation retry uses the same activation key and cannot create duplicate plan history.
|
||
- Define an operational reversal procedure for mistaken approval; do not improvise a downgrade through the upgrade endpoint.
|
||
|
||
## 14. Security and Audit
|
||
|
||
- Validate company tenancy on every company endpoint.
|
||
- Apply least-privilege permissions to payment evidence and internal notes.
|
||
- Restrict file type and size; scan uploads before review/download.
|
||
- Use signed, short-lived file access rather than public URLs.
|
||
- Rate-limit quote generation, evidence uploads, and admin mutations.
|
||
- Record actor, timestamp, previous state, next state, reason, IP/session metadata where permitted, and correlation ID for every material action.
|
||
- Make financial/audit records append-only where practical.
|
||
- Redact sensitive data from logs, analytics, and notification payloads.
|
||
- Define retention rules for evidence and audit data according to applicable law and contract requirements.
|
||
|
||
## 15. Observability and Reporting
|
||
|
||
Track at minimum:
|
||
|
||
- Upgrade options viewed.
|
||
- Quote creation, acceptance, expiry, and cancellation rates.
|
||
- Payment-review turnaround time.
|
||
- Correction and rejection reasons.
|
||
- Approval-to-activation latency.
|
||
- Activation failures and retries.
|
||
- Upgrade conversion by current plan, target plan, cadence, language, and company segment.
|
||
- Incremental recurring/contract value, calculated from plan history rather than UI analytics.
|
||
|
||
Alert on approved requests stuck before activation, repeated worker failures, duplicate-transition errors, unusual override volume, and notification failure spikes.
|
||
|
||
## 16. Testing Strategy
|
||
|
||
### 16.1 Unit tests
|
||
|
||
- Full, half, one-day, leap-year, and boundary-date proration.
|
||
- Currency rounding and minimum-charge rules.
|
||
- Discounts, taxes, fees, and negotiated-price eligibility.
|
||
- Valid and invalid plan transitions.
|
||
- State-transition guards and idempotency.
|
||
- Language selection and fallback.
|
||
|
||
### 16.2 Integration tests
|
||
|
||
- Quote snapshot remains unchanged after catalog price changes.
|
||
- Duplicate active request is rejected under concurrency.
|
||
- Evidence upload is tied to the correct company, request, and quote.
|
||
- Only authorized platform admins can approve.
|
||
- Approval triggers exactly one activation.
|
||
- Activation atomically writes plan history and entitlements.
|
||
- Notification failures do not roll back activation.
|
||
- Expiry and scheduled-renewal workers are idempotent.
|
||
- Stale admin screens cannot approve an already changed request.
|
||
|
||
### 16.3 End-to-end scenarios
|
||
|
||
1. Immediate annual upgrade with exact half-term proration.
|
||
2. Immediate upgrade near renewal using minimum-charge behavior.
|
||
3. Upgrade at renewal, then successful scheduled activation.
|
||
4. Correction required, replacement evidence, approval, and activation.
|
||
5. Rejected evidence with no entitlement change.
|
||
6. Quote expires before approval and requires requoting.
|
||
7. Two admins approve concurrently; only one activation occurs.
|
||
8. Company changes language after quote; existing communication follows the documented snapshot policy.
|
||
9. Arabic flow verifies translations, RTL layout, dates, currency, email, and PDF/payment instructions.
|
||
10. Activation fails after approval and succeeds through idempotent retry.
|
||
11. Unauthorized user and cross-tenant access attempts are denied.
|
||
12. Catalog plan changes while a quote is pending; frozen quote and plan versions remain reproducible.
|
||
|
||
### 16.4 Manual UI testing
|
||
|
||
- Desktop, tablet, and mobile widths.
|
||
- EN/FR LTR and AR RTL.
|
||
- Light and dark themes if supported by the product.
|
||
- Keyboard-only and screen-reader-critical flows.
|
||
- Long French and Arabic content, large currency values, error messages, empty states, upload progress, and slow network behavior.
|
||
|
||
## 17. Delivery Phases
|
||
|
||
### Phase 1 — Policy and contract decisions
|
||
|
||
- Approve proration basis, effective-date rule, quote validity, minimum charges, discount transfer, tax treatment, cancellation, and admin override policy.
|
||
- Define eligible plan transition matrix.
|
||
- Inventory current subscription, plan, payment, role, localization, notification, and entitlement architecture.
|
||
|
||
Exit criterion: no unresolved decision can change stored financial amounts, renewal dates, or activation authorization.
|
||
|
||
### Phase 2 — Data and domain foundation
|
||
|
||
- Add upgrade request, quote, plan history, payment linkage, constraints, indexes, and migrations.
|
||
- Implement state machine, eligibility, quote calculation, and audit events.
|
||
- Add backfill only where required; do not fabricate historical quotes.
|
||
|
||
Exit criterion: domain and migration tests pass, including rollback/forward compatibility.
|
||
|
||
### Phase 3 — Company workflow
|
||
|
||
- Build plan comparison, quote review, acceptance, payment instructions, evidence upload, status tracking, cancellation, and scheduled-upgrade flow.
|
||
- Add EN/FR/AR copy and RTL behavior.
|
||
|
||
Exit criterion: a company admin can complete each allowed path without platform-admin database intervention.
|
||
|
||
### Phase 4 — Platform-admin workflow
|
||
|
||
- Build review queue, evidence review, correction, rejection, approval, override controls, audit view, and activation incident queue.
|
||
|
||
Exit criterion: payment review and recovery are fully operable through authorized product interfaces.
|
||
|
||
### Phase 5 — Activation and communication
|
||
|
||
- Implement atomic activation, entitlement refresh, outbox processing, notifications, expiry worker, and scheduled-renewal activation.
|
||
|
||
Exit criterion: exactly-once business effects are demonstrated under retries and concurrent actions.
|
||
|
||
### Phase 6 — Hardening and release
|
||
|
||
- Complete security review, accessibility audit, localization QA, performance tests, operational dashboards, alerts, runbook, and staged rollout.
|
||
- Pilot with internal/test companies before general availability.
|
||
|
||
Exit criterion: all release blockers are closed and rollback/recovery has been rehearsed.
|
||
|
||
## 18. Definition of Done
|
||
|
||
- All product-policy decisions in Phase 1 are documented and approved.
|
||
- Immediate prorated and renewal-scheduled upgrades work for eligible subscriptions.
|
||
- Financial calculations are reproducible from immutable snapshots.
|
||
- No upgraded feature is accessible before verified payment and successful activation.
|
||
- Subscription and plan history are preserved and auditable.
|
||
- Duplicate requests, duplicate approvals, and duplicate activations are prevented.
|
||
- EN, FR, and AR flows are complete; Arabic is verified RTL.
|
||
- Correct recipients receive localized notifications; ordinary company users do not receive billing notices.
|
||
- Security, accessibility, automated, and manual tests pass.
|
||
- Monitoring, alerts, support documentation, and recovery runbook are operational.
|
||
- Release can be rolled back without corrupting active subscriptions or losing approved-payment records.
|
||
|
||
## 19. Decisions Required Before Coding
|
||
|
||
1. Is proration based on calendar days, exact timestamps, or whole billing months? Recommendation: calendar days in the billing timezone.
|
||
2. Which date controls the price: quote creation, claimed payment, cleared payment, or admin approval? Recommendation: quote is valid through a fixed expiry; after expiry, requote.
|
||
3. How long is a quote valid? Recommendation: 7 days, capped at renewal.
|
||
4. Are taxes included in displayed plan prices, and how is tax recomputed for upgrades?
|
||
5. Do negotiated discounts transfer to target plans? Recommendation: only when explicitly marked transferable.
|
||
6. What is the minimum charge per currency?
|
||
7. Can grace-period subscriptions upgrade, or must overdue balances be cleared first? Recommendation: clear overdue balances first unless a platform admin approves a combined settlement.
|
||
8. Can platform admins override the calculated amount? Recommendation: only with a separate permission, reason, and audit event.
|
||
9. What happens if the company pays after quote expiry? Recommendation: do not activate automatically; reconcile payment against a new approved quote.
|
||
10. Does the company language snapshot remain fixed for the request, or follow later company-language changes? Recommendation: snapshot financial documents; use the current company language for later status notifications only if this distinction is clearly implemented.
|
||
|
||
These are blocking business rules, not implementation details. Coding before resolving them risks incorrect charges, disputed renewal dates, and unauthorized access.
|