Skip to content

feat: ready cdn.databayt.org migration (do not merge until CNAME verified)#272

Merged
abdout merged 9 commits into
mainfrom
feat/cdn-cname-migration
Apr 29, 2026
Merged

feat: ready cdn.databayt.org migration (do not merge until CNAME verified)#272
abdout merged 9 commits into
mainfrom
feat/cdn-cname-migration

Conversation

@abdout
Copy link
Copy Markdown
Contributor

@abdout abdout commented Apr 25, 2026

Summary

Stages all the code changes hogwarts needs to switch from the raw CloudFront URL (d1dlwtcfl0db67.cloudfront.net) to the friendly cdn.databayt.org alias. Adding the alias is purely additive — the original URL keeps working forever — so nothing breaks at any point during this rollout.

Changes

File Change
next.config.ts Add cdn.databayt.org to image remotePatterns alongside the existing d1dlwtcfl0db67.cloudfront.net entry. Both hosts work simultaneously
public/icons/whatsapp/cdn-manifest.json Rewrite 44 URL literals to use cdn.databayt.org. File is a build artifact, not consumed at runtime — flipping it before CNAME goes live is safe
content/docs-en/cdn.mdx Document both URLs, mark the new one as preferred

Required user actions before merging

Do not merge this PR until step 1 passes.

  1. Set up the CNAME in AWS (steps documented in kun/scripts/crawl-anthropic/setup-cname.sh):

    • Route 53: CNAME cdn.databayt.orgd1dlwtcfl0db67.cloudfront.net
    • ACM (us-east-1): request public cert for cdn.databayt.org, validate via DNS
    • CloudFront: add cdn.databayt.org as alternate domain name on the d1dlwtcfl0db67 distribution + attach the ACM cert
    • Verify: curl -sI https://cdn.databayt.org/icons/ic-wa-archived-24.svg returns 200 OK
  2. After this PR merges, flip the Vercel env var:

    • Vercel project → Settings → Environment Variables
    • NEXT_PUBLIC_CDN_DOMAIN: d1dlwtcfl0db67.cloudfront.netcdn.databayt.org
    • Apply to Production + Preview + Development
    • Trigger a redeploy
  3. Optionally, flip your local .env to match (gitignored, not included here).

The asset() helper at src/lib/asset-url.ts reads NEXT_PUBLIC_CDN_DOMAIN at build time, so all 4 component callers (welcome-dialog, wa-tokens, chat-wallpaper, apply-overview-client) pick up the new host automatically once step 2 lands.

Why this is zero-risk

CloudFront's "Alternate domain name" feature is purely additive. The original *.cloudfront.net distribution domain ALWAYS resolves and cannot be removed. So:

  • Before CNAME setup: only old URL resolves → nothing changed for hogwarts
  • After CNAME setup: both URLs resolve → hogwarts still works (still uses old via env)
  • After Vercel env flip + redeploy: new URL is preferred, but old URL stays valid for any cached HTML, third-party embeds, or deep links

Out of scope

  • The .env file (gitignored — manual user step)
  • Vercel env var flip (manual user step in Vercel dashboard)
  • The actual CNAME provisioning in AWS (manual user step or setup-cname.sh)
  • Equivalent flip in kun repo's data.ts CDN_BASE (one-line follow-up PR after CNAME verified)

Test plan

  • next.config.ts adds new hostname (no removal)
  • cdn-manifest.json: 44 URLs flipped, 0 stragglers (grep -c "d1dlwtcfl0db67" public/icons/whatsapp/cdn-manifest.json returns 0)
  • No source file imports cdn-manifest.json (verified via grep)
  • After CNAME live + env flip + redeploy: open hogwarts production, network tab shows cdn.databayt.org requests
  • WhatsApp icons render in /messaging/mobile/chat
  • Welcome dialog assets render

🤖 Generated with Claude Code

…fied)

Stages all code changes needed to migrate hogwarts from raw cloudfront URL
(d1dlwtcfl0db67.cloudfront.net) to the friendly cdn.databayt.org alias.

Adding the alias is purely additive — original URL keeps working forever, so
nothing breaks at any point during this rollout.

Changes:
- next.config.ts: add cdn.databayt.org to image remotePatterns alongside the
  existing d1dlwtcfl0db67.cloudfront.net entry. Both work.
- public/icons/whatsapp/cdn-manifest.json: rewrite 44 URL literals to use
  the new host. File is a build artifact, not consumed at runtime — safe to
  flip even before CNAME goes live.
- content/docs-en/cdn.mdx: document both URLs, note the new one is preferred.

Out of scope (requires user action):
1. AWS console: add cdn.databayt.org as alternate domain name on the
   d1dlwtcfl0db67 distribution + ACM cert (us-east-1). See
   kun/scripts/crawl-anthropic/setup-cname.sh for steps.
2. After CNAME verified live (curl returns 200), flip NEXT_PUBLIC_CDN_DOMAIN
   in Vercel project env from d1dlwtcfl0db67.cloudfront.net to cdn.databayt.org.
3. Optionally update local .env to match (gitignored — not in this PR).

The asset() helper at src/lib/asset-url.ts reads NEXT_PUBLIC_CDN_DOMAIN at
build time, so all 4 component callers pick up the new host automatically
once the env flip is deployed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hogwarts Ready Ready Preview, Comment Apr 26, 2026 6:27am

cdn.databayt.org is already in use by an active Vercel project — using a
free subdomain instead. DNS already provisioned via Vercel CLI; CAA record
for amazon.com added so ACM cert can issue.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DNS already provisioned in Vercel (specific CNAME overrides wildcard
that would have routed to hogwarts).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
abdout and others added 2 commits April 25, 2026 21:07
…d skips

Personal and location step content components consumed useWizardValidation
directly without registering an onSave handler, so the footer's save-and-skip
button silently no-op'd. Register a setOnSave that runs the same saveAndNext
calls as onNext (without navigating); footer's onSkipToComplete handles the
redirect to /students after the save resolves. Cleanup on unmount prevents
handler leakage into other steps.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
72 → 236 tests across 14 files. Adds Vitest coverage for the RBAC
matrix, query builders, list-params, video upload/owner/review,
enrollments, teacher stats, and get-proposable-lessons.

Bug fixes:
- get-proposable-lessons.ts had no auth check — anyone calling the
  server action could enumerate the catalog. Added auth() + role gate
  for DEVELOPER/ADMIN/TEACHER.
- dashboard/parent/__tests__/actions.test.ts mocked db.catalogLesson
  but action uses db.lesson — test threw before assertions.
- not-admin/content.tsx had dictionary: any, hardcoded English, and
  invalid href="/" without locale. Now typed, locale-aware, fixed href.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
abdout and others added 2 commits April 26, 2026 07:29
…otificationTypes

- Replace 21-entry hardcoded list in getAllowedNotificationTypes with
  Object.values(NotificationType) — list had drifted from the Prisma enum
  (missed setup_guide, absence_intention, absence_intention_decision)
- Add NOTIFICATION_FILTER_TYPES constant referenced by tests
- New: rbac-matrix.test.ts (34 tests) — exhaustive UserRole × NotificationType
  matrix so future enum additions fail loudly until the role allow-list is
  reviewed
- New: edge-cases.test.ts (10 tests) — expiration derivation, tenant-scoped
  markAll, subscription unique-key, normal vs overnight quiet-hours windows
- New: poll-actions.test.ts (5 tests) — session/tenant guards, getDisplayText
  translation pipeline, Date → ISO serialization
- Fix stale enum copies in config.test.ts (23→24 types, 4→5 channels) and
  validation.test.ts (24 types + new whatsapp channel coverage)
- Fix actions.test.ts: add db.\$transaction mock for updateNotificationPreferences
  which wraps upserts in a transaction

Notification block: 200/204 → 254/254 tests green; 0 TypeScript errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ontribution map, +87 tests

Block-level fixes
- Avatar upload: was a no-op stub returning fake success; now persists via the
  shared S3 pipeline (file/upload/actions::uploadFile) with MIME and 5MB caps.
- updateProfileSettings: same lie (validated then no-op write); now returns
  NOT_IMPLEMENTED until the User schema gains settings columns.
- Contribution graph timezone bug: getYearDateRange used local-time
  new Date(year, 0, 1) while formatDateKey was UTC, shifting Jan 1 to Dec 31
  in any positive UTC offset (Riyadh +3 etc.). Switched the helper to
  Date.UTC + setUTCDate so the calendar is timezone-stable.
- Added viewerPermission (OWNER/ADMIN/STAFF/RELATED/PUBLIC) to
  getProfileBasicData so the UI can mask emailAddress/employeeId for non-admins.
- Replaced hardcoded English error strings in edit-role-actions.ts and
  detail/actions.ts with action error codes (i18n compliance).
- Removed dead Octicon icon-reference grid that was leaking debug UI into
  the profile overview tab.
- Documented detail/actions.ts as foundation code for a future admin
  user-detail page (currently dead, kept intentionally).

Tests (5 → 92)
- __tests__/actions.test.ts: rewrote weak prisma-mock smoke tests into 35
  real tests covering auth/tenant gates, schoolId scoping, role mapping,
  pinned items, activity logging, viewerPermission flagging.
- __tests__/validation.test.ts (new, 22): every Zod schema + edge cases.
- __tests__/contribution.test.ts (new, 12): year validation, leap-year day
  count, activity aggregation, streak math, missing-role-record path.
- detail/__tests__/permissions.test.ts (new, 23): full RBAC matrix.
- tests/e2e/profile/profile-flows.spec.ts (new, 6 specs): own profile,
  edit form, view-other, auth gate, teacher self-service.

Infra
- Added NOT_IMPLEMENTED to ACTION_ERRORS for honest stub responses.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
return `http://${host}/en/profile`
}

function profileForId(userId: string, host = DEMO_HOST) {
abdout and others added 2 commits April 26, 2026 08:02
Set up the rails for the wider docs cleanup:

- Register Callout, CardGrid, DocCard MDX components so doc authors stop
  inlining JSX/Tailwind grids in pages.
- Add docs/STYLE.md as the single source of truth for voice, frontmatter,
  length caps, and component usage. Banishes per-doc Production Readiness
  / Known Issues sections.
- Add scripts/docs-lint.mjs (pnpm docs:lint) — flags duplicate body H1,
  placeholder descriptions, hardcoded text-* / font-* classes, broken
  /docs/<slug> links, files over category caps. Emits tmp/docs-link-audit.json
  with --audit.
- Add scripts/docs-strip-h1.mjs and run it: 14 surviving docs lose their
  duplicate body H1 (the renderer already prints frontmatter title as <h1>).
  Files slated for Phase 2 deletion are skipped.
- Register 3 orphan MDX files in meta.json: cdn, fees, document-intelligence.
  ai-document-processing remains orphaned — Phase 2 folds it into
  document-intelligence.

Lint baseline: 117 files / 54,382 lines / 89 → 77 issues.
…code

Self-QA caught one missed translation leak in updatePinnedItems:
"Maximum 6 pinned items allowed" → VALIDATION_ERROR + MAX_PINNED_EXCEEDED detail.

Strengthens the corresponding test to assert both error code and detail.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@abdout abdout merged commit 47b6042 into main Apr 29, 2026
7 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs Documentation area: platform Platform dashboard code type: config type: tests Test changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants