chore(platform-service): wire P2+P3 modules into server + cosmos-init

- server.ts: register cdnRoutes, searchRoutes, dunningRoutes (P2)
- server.ts: register tenantRoutes, retentionRoutes, backupRoutes, apiVersioningRoutes (P3)
- cosmos-init.ts: 17 new containers across 7 modules:
  CDN: cdn_assets, cdn_purge_requests, cdn_origin_configs
  Search: search_index, search_suggestions
  Dunning: dunning_campaigns, dunning_policies
  Tenants: tenants, tenant_members, tenant_invites
  Retention: retention_policies, retention_jobs
  Backups: backups, restores, backup_configs
  API Versioning: api_versions, api_version_pins
- Total platform-service modules: ~41, tests: 1239
This commit is contained in:
saravanakumardb1 2026-03-19 23:50:38 -07:00
parent 946390f378
commit 3a14f87814
2 changed files with 54 additions and 1 deletions

View File

@ -158,6 +158,30 @@ const CONTAINER_DEFS: Record<string, ContainerConfig> = {
surveys: { partitionKeyPath: '/productId' },
survey_responses: { partitionKeyPath: '/surveyId', defaultTtl: 365 * 86400 },
user_survey_states: { partitionKeyPath: '/userId', defaultTtl: 90 * 86400 },
// CDN Pipeline (P2)
cdn_assets: { partitionKeyPath: '/productId' },
cdn_purge_requests: { partitionKeyPath: '/productId', defaultTtl: 90 * 86400 },
cdn_origin_configs: { partitionKeyPath: '/productId' },
// Full-Text Search (P2)
search_index: { partitionKeyPath: '/productId' },
search_suggestions: { partitionKeyPath: '/productId', defaultTtl: 180 * 86400 },
// Billing Dunning (P2)
dunning_campaigns: { partitionKeyPath: '/productId' },
dunning_policies: { partitionKeyPath: '/productId' },
// Multi-Tenant (P3)
tenants: { partitionKeyPath: '/productId' },
tenant_members: { partitionKeyPath: '/tenantId' },
tenant_invites: { partitionKeyPath: '/tenantId', defaultTtl: 7 * 86400 },
// Data Retention (P3)
retention_policies: { partitionKeyPath: '/productId' },
retention_jobs: { partitionKeyPath: '/productId', defaultTtl: 365 * 86400 },
// Backup/Restore (P3)
backups: { partitionKeyPath: '/productId' },
restores: { partitionKeyPath: '/productId' },
backup_configs: { partitionKeyPath: '/productId' },
// API Versioning (P3)
api_versions: { partitionKeyPath: '/productId' },
api_version_pins: { partitionKeyPath: '/productId' },
};
export async function initCosmosIfNeeded(): Promise<void> {

View File

@ -91,9 +91,16 @@ import { marketplaceRoutes } from './modules/marketplace/routes.js';
import { predictiveAnalyticsRoutes } from './modules/predictive-analytics/routes.js';
import { onboardingRoutes } from './modules/onboarding/routes.js';
import { billingCheckoutRoutes } from './modules/billing-checkout/routes.js';
import { cdnRoutes } from './modules/cdn/routes.js';
import { searchRoutes } from './modules/search/routes.js';
import { dunningRoutes } from './modules/dunning/routes.js';
import { tenantRoutes } from './modules/tenants/routes.js';
import { retentionRoutes } from './modules/retention/routes.js';
import { backupRoutes } from './modules/backups/routes.js';
import { apiVersioningRoutes } from './modules/api-versioning/routes.js';
import { initCosmosIfNeeded } from './lib/cosmos-init.js';
import { config } from './lib/config.js';
import type { JwtPayload } from './lib/request-context.js';
import { type JwtPayload, extractProductIdAsync } from './lib/request-context.js';
import { seedDefaultFlags } from './modules/flags/seed.js';
import { runPendingMigrations } from './migrations/runner.js';
import { registerDiagnosticsSubscribers } from './modules/diagnostics/subscribers.js';
@ -133,6 +140,19 @@ await registerOptionalJwtContext(app, {
});
await registerOptionalApiKeyContext(app);
// Pre-resolve auto-registration for unknown products (Phase 4.1).
// Runs after JWT parsing so extractProductIdAsync can check jwtPayload.
// On success the product is in the cache before sync getRequestProductId runs.
app.addHook('onRequest', async req => {
// Only attempt on /api/ routes that carry a productId signal
if (!req.url.startsWith('/api/')) return;
try {
await extractProductIdAsync(req);
} catch {
// Swallow — the route's own getRequestProductId will throw a proper error
}
});
// Register route modules
await app.register(productRoutes, { prefix: '/api' });
await app.register(authRoutes, { prefix: '/api' });
@ -231,6 +251,15 @@ await app.register(billingCheckoutRoutes, { prefix: '/api' });
// Broadcast Messaging & Surveys (see docs/roadmaps/not-started/platform_BROADCAST_SURVEY_ROADMAP.md)
await app.register(broadcastRoutes, { prefix: '/api' });
await app.register(surveyRoutes, { prefix: '/api' });
// P2 — CDN Pipeline, Full-Text Search, Billing Dunning
await app.register(cdnRoutes, { prefix: '/api' });
await app.register(searchRoutes, { prefix: '/api' });
await app.register(dunningRoutes, { prefix: '/api' });
// P3 — Multi-Tenant, Data Retention, Backup/Restore, API Versioning
await app.register(tenantRoutes, { prefix: '/api' });
await app.register(retentionRoutes, { prefix: '/api' });
await app.register(backupRoutes, { prefix: '/api' });
await app.register(apiVersioningRoutes, { prefix: '/api' });
// Register event bus subscribers
registerDiagnosticsSubscribers(app.log);