Generated: 2026-05-20
Scope: structural issues in krisyotam.com, with emphasis on making the codebase leaner, easier to navigate, and safer to change by August. This audit does not cover visual design polish or content quality.
The main problem is not one bad subsystem. The project has several parallel sources of truth that have drifted:
data/ and stale public/data/ artifacts.src/app mixes route modules with content payloads.public/scripts contains both browser assets and private operational tooling.The highest-value August target is:
Evidence:
src/app/(content)/[type]/config.tsnext.config.mjssrc/lib/seo.tssrc/lib/content.tssrc/lib/graph.tssrc/app/sitemap.tssrc/app/api/content/search/route.tssrc/app/api/content/md/[slug]/route.tssrc/app/api/system/utils/route.tspublic/scripts/dev/syncContent.jspublic/scripts/dev/slugCollisions.jspublic/scripts/prod/magic-urls.jspublic/scripts/dev/generateMetadata.jsWhy it matters:
Adding or changing a content type requires edits in many unrelated files. Some lists include documents, til, now, scripts, notebooks, or sequences; others exclude them. That makes behavior hard to predict across feeds, search, sitemap, sexy URLs, and sync.
Fix:
Create a single registry that defines each content surface:
Suggested file:
src/config/contentRegistry.ts for app/runtime code.scripts/lib/contentRegistry.mjs or generated JSON for CommonJS scripts and next.config.mjs.First batch:
src/lib/seo.ts, src/lib/content.ts, src/app/sitemap.ts, src/app/api/content/search/route.ts.Evidence:
data/ via src/lib/db.ts.data/*.db is explicitly tracked by .gitignore.public/data/content.db, public/data/media.db, and public/data/system.db exist as zero-byte files.public/scripts/doc/syncDocs.js resolves ../../data/content.db from inside public/scripts/doc, which lands at public/data/content.db.public/scripts/dev/syncNotebooks.js has the same public-data path issue.public/scripts/dev/blogActivity.js and public/scripts/prod/magic-urls.js still reference public DB paths.Why it matters:
The app reads one database root while some scripts mutate or inspect another. This creates silent drift and makes script output untrustworthy. It also keeps fake DB files under a web-served directory.
Fix:
Make root data/ the only SQLite root. Add a shared script helper:
scripts/lib/paths.mjsPROJECT_ROOT, DATA_DIR, CONTENT_DIR, and dbPath(name)KRISYOTAM_DATA_DIR and KRISYOTAM_CONTENT_DIRFirst batch:
syncDocs.js, syncNotebooks.js, blogActivity.js, and magic-urls.js to use the helper.public/data/*.db.data/ are source snapshots and which are derived artifacts.git.js fail on core sync errors instead of catching and continuing.Evidence:
next.config.mjs builds sexy URL rewrites directly from content.db.src/lib/canonical-url.ts mirrors the type list and reserved slug rules.src/app/(content)/[type]/[category]/[slug]/page.tsx uses /${slug} for metadata but hierarchical URLs for JSON-LD and breadcrumbs./${slug} in src/components/content/table.tsx, src/components/content/directory.tsx, and src/components/content/mediaCard.tsx.route fields that are ignored by shared components.Why it matters:
The site convention is sexy URLs. Today that rule is implemented partly by rewrite generation, partly by helper functions, and partly by UI component fallbacks. SEO, JSON-LD, sitemap, breadcrumbs, and client links can disagree.
Fix:
Normalize URLs server-side and pass item.url everywhere. Components should render one URL field instead of rebuilding URLs locally.
First batch:
url.getCanonicalContentUrl or a generated route manifest in metadata, JSON-LD, breadcrumbs, citations, and view trackers.src/app contains content payloadsEvidence:
src/app/(content)/til/content/*.mdxsrc/app/(content)/now/content/*.mdxsrc/app/(misc)/surveys/content/*.survey.mdWhy it matters:
The App Router tree should show routing and rendering ownership. Source content inside route folders makes it harder to scan the app tree and blurs the line between code and authored content.
Fix:
Move these payloads to src/content/... or the external content repo, then keep src/app limited to route modules, layouts, loading states, route-local clients, and route-local styles.
First batch:
src/lib/til.ts and src/lib/now.ts.Evidence:
src/app/(content)/til/page.tsxsrc/app/(content)/til/[slug]/page.tsxsrc/app/(content)/now/page.tsxsrc/app/(content)/now/[slug]/page.tsxWhy it matters:
Index and detail pages repeat full-collection loading and MDX import logic. Detail routes should not scale with collection size.
Fix:
Extract loaders:
getTilEntries()getTilEntry(slug)getNowEntries()getNowEntry(slug)Then use collection loaders only for indexes and static params.
Evidence:
src/app/(info) is empty.src/app/(media) is empty.(tracking).(misc) include several unrelated page families.Why it matters:
Empty and vague groups weaken the mental map. The App Router tree should answer "where does this page belong?" quickly.
Fix:
Remove empty route groups or add a short route ownership note in .config/.codex/docs/routes.md and the architecture map.
Evidence:
src/components/layout/header.tsx starts with "use client".Why it matters:
Mostly static header markup should not widen the client boundary. The interactive part should be a small island.
Fix:
Split into:
Evidence:
src/app/(content)/[type]/client.tsxsrc/app/(content)/til/client.tsxsrc/app/(content)/now/client.tsxsrc/app/(content)/scripts/client.tsxsrc/app/(content)/sequences/client.tsxRepeated logic includes:
Why it matters:
Every new collection page copies decisions from older pages. Small behavior fixes then require many edits.
Fix:
Extract:
src/hooks/useContentListingState.tssrc/components/content/CollectionShell.tsxsrc/components/content/FacetIndex.tsxKeep route clients responsible only for data shape and item renderer choice.
Evidence:
src/components/media/tracking-overview.tsx already contains a shared renderer.src/app/(tracking)/games/client.tsx still hand-rolls tabs, stat strips, sections, pagination, and empty states.src/app/(tracking)/film/watched/client.tsx and src/app/(tracking)/anime/watched/client.tsx repeat filter and grid scaffolding.Fix:
Extend TrackingOverview, then add a generic TrackingGridBrowser for watched/read/played lists.
PageDescription owns too many jobsEvidence:
src/components/layout/page-description.tsxCurrent responsibilities:
Fix:
Extract:
parseMarkdownLinks helper with testsglobals.css is a catch-allEvidence:
src/app/globals.css is about 1,979 lines.Why it matters:
Global CSS is now a shared junk drawer. It is hard to know whether a class is global by design, legacy, or route-specific.
Fix:
Move domain styles into src/app/styles/core/* and import them through a single file:
base.csstypography.csscode.csscomments.cssfootnotes.csssidenotes.cssprint.csscards.cssmotion.cssKeep globals.css as the import root plus true app-wide tokens.
Evidence:
src/app/styles/themes/default.css.dark definitionsFix:
Use layered token groups or generate theme CSS from one source. The first target is no behavior change: reduce duplicate declarations while preserving fallback behavior.
public/Evidence:
public/scripts/dev/*public/scripts/doc/*public/scripts/prose/*public/scripts/verse/*public/scripts/doc/filelist.txtWhy it matters:
Only browser-delivered scripts belong under public/. Commit tooling, DB mutators, importers, document sync, and prose tools should not be web-served.
Fix:
Target shape:
public/scripts/footnotes.jspublic/scripts/sidenotes.jspublic/scripts/prod/* only if browser-delivered or server-used from public pathscripts/dev/*scripts/doc/*scripts/prose/*scripts/verse/*scripts/lib/*Migration needs compatibility shims because project memory currently says script subdirectories are fixed under public/scripts/{auth,dev,doc,prod,prose,verse}. This should be changed deliberately in the architecture docs when the migration starts.
Evidence:
public/scripts/dev/syncContent.js still documents public/scripts/keep.public/scripts/dev/generateMetadata.js hardcodes PROJECT_ROOT = '/home/krisyotam/dev/krisyotam.com'.Fix:
After the path helper lands, convert scripts one family at a time and remove stale comments while touching each file.
Evidence:
src/lib/media-db.ts is about 837 lines.src/lib/data.ts is about 713 lines.src/lib/system-db.ts is about 620 lines.Fix:
Split by domain once the registry exists:
Avoid splitting before the registry and DB path fixes, or it will preserve the same drift in more files.
Evidence:
vitest.config.ts uses Node environment only.Fix:
Start with tests that protect the refactors:
data/ by default.Add jsdom only for components that actually need browser interaction.
This is the cleanest split between Claude and Codex without both agents touching the same files at once.
Files likely touched:
src/lib/db.tsscripts/lib/paths.mjspublic/scripts/doc/syncDocs.jspublic/scripts/dev/syncNotebooks.jspublic/scripts/dev/blogActivity.jspublic/scripts/prod/magic-urls.jspublic/scripts/dev/git.jsGoal:
Fix DB root drift and make script path resolution trustworthy.
Files likely touched:
src/app/(content)/[type]/config.tssrc/lib/seo.tssrc/lib/content.tssrc/app/sitemap.tssrc/app/api/content/search/route.tsGoal:
Create the content registry and convert read-only consumers.
Files likely touched:
src/lib/canonical-url.tssrc/app/(content)/[type]/[category]/[slug]/page.tsxsrc/app/(content)/[type]/page.tsxsrc/components/content/table.tsxsrc/components/content/directory.tsxsrc/components/content/mediaCard.tsxGoal:
Normalize canonical URLs once and pass item.url through shared components.
Files likely touched:
src/app/(content)/til/page.tsxsrc/app/(content)/til/[slug]/page.tsxsrc/app/(content)/now/page.tsxsrc/app/(content)/now/[slug]/page.tsxsrc/lib/til.tssrc/lib/now.tsGoal:
Extract TIL and Now loaders before moving content out of route folders.
globals.css extraction; the other only reviews imports.public/: do only after path helper and docs are updated.item.url.PageDescription client islands.globals.css.public/.No claudeAudit.md was present in the repo root when this file was written. When Claude's file appears, merge by theme rather than by agent:
Deduplicate by file path before assigning fixes. The files most likely to attract conflicts are:
src/app/(content)/[type]/config.tssrc/lib/seo.tssrc/lib/content.tssrc/lib/data.tssrc/lib/canonical-url.tsnext.config.mjssrc/app/globals.csspublic/scripts/dev/git.jspublic/scripts/dev/syncContent.js