Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PWYAJWwUpthUkscWT9t3oz
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PWYAJWwUpthUkscWT9t3oz
…arget Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PWYAJWwUpthUkscWT9t3oz
Drop --base=/db5/ from the djangobuilder5 build, build djangobuilder.io with --base=/legacy/, and rewrite the hosting config: /legacy/** and /db4/** go to their own index.html, everything else to the root (djangobuilder5) index, and /db5 plus /db5/** redirect to /. The subfolder rewrites now carry a leading slash; without it the emulator never matched them, so deep links under /db4/ fell through to the root app. Remove the stale firebase.json copy in the .io package. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PWYAJWwUpthUkscWT9t3oz
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PWYAJWwUpthUkscWT9t3oz
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
…ns, (Legacy) title The banner replaces the earlier 'may be end-of-lifed soon' alert in the same slot, since a new version at / supersedes that message. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
…082 and web.app Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
…ff the key's referrer list Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
mmcardle
marked this pull request as ready for review
September 20, 2026 11:04
…estore Projects created before the Dec-2024 core refactor store field and relationship types as full Django paths (django.db.models.DateTimeField, django.db.models.ForeignKey) and relationship targets as full class paths (django.contrib.auth.models.User). The core registries are keyed by bare class name, so FieldTypes[type] came back undefined and the dashboard threw 'Unknown field type: django.db.models.DateTimeField' for any such project. The legacy app and db4 both normalise on read; now the mapper does too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
…d of throwing Five historical field types (AutoField, BigAutoField, CommaSeparatedIntegerField, IPAddressField, NullBooleanField) no longer exist in the core registry, so one such field in one project would still white-screen the dashboard after name normalisation. Mirror the existing unresolved-target policy: warn and skip that field or relationship, keep rendering the rest. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
A select whose value matches no option renders the first option, so a legacy CommaSeparatedIntegerField field displayed as ArrayField while being skipped from generation. List the stored type as '<type> (unsupported)' until a current type is chosen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
bun run audit_legacy_data <development|staging|production> reads the five collections through the Firestore REST API as the project owner (using the Firebase CLI login, or application-default credentials when present), and reports: dotted pre-2024 type names (normalised on read), field/relationship types the core no longer knows, unresolved targets and parents, the django_version distribution incl. pre-Django-3 projects, dangling refs and orphans, and every project whose generated code or displayed version would differ from what its owner built, with reasons. Writes a JSON report at the repo root. Nothing is written to Firestore. Classification is pure and unit-tested; the CLI only fetches and prints. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
…onment argument Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
indexOf('--out') is -1 without the flag, so the filter 'i !== outFlag + 1'
discarded argv[0]. Extract parseAuditArgs with tests.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
…d --full Listing every document costs one read per document and exhausted the production project's Spark-plan daily quota (HTTP 429) part-way through. Default mode now uses count aggregations (~1 read per 1,000 matches) plus targeted queries: prefix ranges for the pre-2024 dotted names, an IN filter for the five retired field types, and < 3 comparisons for pre-Django-3 versions. Only offending documents are fetched, and their owning project is found by querying the parent maps upward (3 reads per field, capped at 100). --full keeps the per-document scan for dangling refs/orphans/missing types, with the read cost printed first. 429s now explain the quota and its reset. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
Firestore rejects unquoted path segments that do not match [a-zA-Z_][a-zA-Z_0-9]*, and auto ids can start with a digit (fields.02haSl3F41qosZRsDUp6 -> HTTP 400). Always backtick-quote the id. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
djangobuilder5builds for/,djangobuilder.iofor/legacy/,djangobuilder4stays at/db4/.firebase.jsonrewrites/legacy/**and/db4/**to their ownindex.html, everything else to the root index, and 301s/db5and/db5/**to/.script/assemble_site.shis the only place that knows the layout.script/deploy.shandmake deployuse it; newmake serve_siteserves the assembled site on the Firebase hosting emulator. The stalepackages/djangobuilder.io/firebase.jsonis removed.src/lib/legacyHash.tsin djangobuilder5 rewrites legacy hash URLs at startup (/#/project/<id>→/project/<id>,/#/login/→/login,/#/action?…→/action?…,/#/verify/<code>and/#/reset/<code>→/action?mode=…, unknown →/). Covers old bookmarks, in-flight verification emails and either form of the Firebase console action URL.django.db.models.DateTimeField,django.db.models.ForeignKeyand targets likedjango.contrib.auth.models.User; djangobuilder5 looked those up verbatim and the dashboard threwUnknown field type: django.db.models.DateTimeField(seen on staging). The Firestore mapper now normalises them to registry keys (as the legacy app and db4 already did on read). Five historical field types no longer exist in core at all (AutoField,BigAutoField,CommaSeparatedIntegerField,IPAddressField,NullBooleanField), so the core adapter now skips an unknown field or relationship type with a console warning instead of throwing, and the model editor shows such a field's stored type as<type> (unsupported)instead of silently displaying the first option.bun run audit_legacy_data <development|staging|production>is a read-only, quota-friendly Firestore audit (count aggregations + targeted queries, a few dozen reads regardless of size) that reports pre-2024 dotted names, fields using the five retired types, projects below Django 3, and every affected project with owner uid and reason.--fullopts into the one-read-per-document integrity scan with its cost printed first. Pure classifier + query builders with unit tests; writeslegacy-data-audit.<env>.json./legacy/. The legacy app gets a dismissibleLegacyBannerlinking to/(replacing the end-of-life alert), a base-aware email continue URL (emailActionContinueUrl), relative manifest icons, and the tab title "Django Builder (Legacy)".index.htmlfiles carry the right asset bases, and uploads onesite_distartifact.docs/deployment.mdwith the environment URLs (dev.djangobuilder.io, staging.djangobuilder.io, djangobuilder.io), layout, local serve, deploy and the manual cut-over checklist. README, AGENTS and the package docs now cover djangobuilder5. Spec and plan underdocs/superpowers/.Verified
bun run lint,bun run test(174 core / 9 io / 220 db5),bun run build, db5type-check: all green./db5*→/301,/legacy→/legacy/301, deep links under/,/legacy/and/db4/resolve to the right app, legacy favicon/manifest/icons 200, both tab titles, banner href/, nav "Legacy UI" href/legacy/./#/project/<id>rewritten in place to/project/<id>with the builder open →/legacy/#/project/<id>opens the same project in the legacy app through the shared session.migrate,check, its 4 generated tests, pages 200, a Post created via the DRF API and via the HTML form.django.contrib.auth.models.Usertarget, a retiredCommaSeparatedIntegerField). Pre-fix build reproduced the exact staging error and blanked the page; fixed build renders the dashboard card, generatesmodels.pywithDateTimeField,CharField(max_length=30)andForeignKey("auth.User", …), skips the retired field with one warning, and the editor labels itCommaSeparatedIntegerField (unsupported).Not in this PR (cut-over checklist in
docs/deployment.md)https://djangobuilder.io/action(the shim keeps the old value working meanwhile).Test plan
make serve_site→/,/legacy/,/db4/load;/db5/xredirects to/bun run audit_legacy_data production→ review affected projects before the production deploymake deploy name=staging→ sign in on https://staging.djangobuilder.io/projects with an account that has pre-2024 projects; dashboard and builder loadmake deploy name=production→ repeat on https://djangobuilder.io/🤖 Generated with Claude Code
https://claude.ai/code/session_01Fhe72RA6v4kAgNWgxm9fge