Coffee journaling on ATProto (alpha) alpha.arabica.social
coffee

refactor: move web/static to static directory

Move static assets from web/static/ to top-level static/ directory
for a cleaner project structure. Update all references in:
- flake.nix
- default.nix
- justfile
- .gitignore
- .gitattributes
- internal/routing/routing.go
- deploy/Dockerfile
- CLAUDE.md

pdewey.com 5613d88f 4daf735b

verified
+13 -19
+1
.cells/cells.jsonl
··· 37 37 {"id":"01KGB1KDNNZZ7ZDA5NCK0T4E1G","title":"Create shared entity table components for profile and manage pages","description":"## Summary\nRefactor the profile and manage page tables to use shared components, reducing duplication and improving maintainability.\n\n## Current State\n- `manage_partial.templ` has tables for beans, roasters, grinders, brewers with Edit/Delete actions\n- `profile_partial.templ` has similar tables but without actions\n- Beans on profile are split into \"Open Bags\" and \"Closed Bags\" sections\n- Significant HTML/structure duplication between the two files\n\n## Proposed Solution\nCreate shared table components with configurable props:\n\n### Shared Components to Create\n1. **BeansTable** - shared beans table component\n2. **RoastersTable** - shared roasters table component \n3. **GrindersTable** - shared grinders table component\n4. **BrewersTable** - shared brewers table component\n\n### Props Pattern\nEach component should accept props that control behavior:\n\n```go\ntype EntityTableProps struct {\n Items []*models.Entity\n ShowActions bool // Whether to render Edit/Delete column\n // Other entity-specific options as needed\n}\n```\n\n### Beans Table Special Handling\nThe beans table has unique requirements:\n- Manage page: single table with Status column, shows all beans\n- Profile page: split into Open/Closed sections, no Status column\n\nOptions to handle this:\n1. **Single component with `ShowStatus` prop** - manage uses it, profile calls it twice with filtered lists\n2. **`GroupByStatus` prop** - component internally groups and renders sections\n3. Keep beans separate if complexity doesn't warrant sharing\n\nRecommend option 1 - simpler, profile already filters beans via `filterOpenBeans`/`filterClosedBeans`.\n\n### Actions Implementation\nWhen `ShowActions: true`:\n- Render action column header\n- Render Edit button with `hx-get=\"/api/modals/{entity}/{rkey}\"`\n- Render Delete button with `hx-delete=\"/api/{entities}/{rkey}\"`\n\n### Files to Modify\n- `internal/web/components/manage_partial.templ` - use shared components\n- `internal/web/components/profile_partial.templ` - use shared components\n- `internal/web/components/entity_tables.templ` (new) - shared table components\n\n### Acceptance Criteria\n- [ ] Shared table components created in `entity_tables.templ`\n- [ ] `manage_partial.templ` refactored to use shared components\n- [ ] `profile_partial.templ` refactored to use shared components\n- [ ] Actions can be enabled/disabled via props\n- [ ] No visual regressions on manage page\n- [ ] No visual regressions on profile page\n- [ ] `templ generate` runs successfully\n- [ ] Tests pass (if any)","status":"completed","priority":"normal","assignee":"patrick","labels":["frontend","refactoring"],"created_at":"2026-01-31T22:08:29.877786981Z","updated_at":"2026-01-31T22:16:42.669635082Z","completed_at":"2026-01-31T22:16:42.657711384Z"} 38 38 {"id":"01KGB2WBMP539SFSKZCKJAYH0C","title":"Prevent line wrap between emoji and text in table headers","description":"Add whitespace-nowrap to table header cells to prevent the emoji and column name from wrapping onto separate lines.","status":"completed","priority":"normal","assignee":"patrick","labels":["frontend"],"created_at":"2026-01-31T22:30:51.286845962Z","updated_at":"2026-01-31T22:31:23.380048647Z","completed_at":"2026-01-31T22:31:23.369060496Z"} 39 39 {"id":"01KGBF5Q2KJ8PZNSMJPFFF31C8","title":"Add AT Protocol explanation page","description":"Create a page explaining what the AT Protocol is that the footer link redirects to instead of atproto.com.\n\nAcceptance criteria:\n- New /atproto page explaining the AT Protocol\n- Footer AT Protocol link redirects to /atproto instead of external site\n- Page matches site design system\n- Explains what AT Protocol is and how Arabica uses it\n- Links to atproto.com for those who want more info","status":"claimed","priority":"normal","assignee":"patrick","created_at":"2026-02-01T02:05:40.819263564Z","updated_at":"2026-02-01T02:10:19.29363426Z","notes":[{"timestamp":"2026-02-01T02:10:19.279321594Z","author":"patrick","message":"Initial implementation complete:\n- Created /atproto page with AT Protocol explanation\n- Updated footer link to point to /atproto instead of external site\n- Added route and handler\n- Page covers: PDS, DIDs, Lexicons, AT-URIs, how Arabica uses ATProto\n- Includes links to atproto.com for more info\nReady for review and final polish"}]} 40 + {"id":"01KGBM1YCGZRNTVCJDZFV3100R","title":"Move web/static to static directory","description":"Move web/static directory to top-level static directory and update all references across the codebase.\n\nFiles to update:\n- flake.nix (tailwindcss paths)\n- .gitignore (output.css path)\n- justfile (tailwindcss paths)\n- default.nix (tailwindcss paths)\n- .gitattributes (vendored JS paths)\n- internal/routing/routing.go (file server path)\n- deploy/Dockerfile (COPY command)\n- CLAUDE.md (documentation)\n\nAcceptance criteria:\n- web/static moved to static/\n- All references updated\n- Server still serves static files correctly\n- Tailwind CSS build still works","status":"completed","priority":"normal","assignee":"patrick","created_at":"2026-02-01T03:31:00.112467261Z","updated_at":"2026-02-01T03:32:59.754877212Z","completed_at":"2026-02-01T03:32:59.739794374Z"}
+2 -2
.gitattributes
··· 1 1 *.tmpl linguist-language=go-template 2 2 3 - web/static/js/alpine.min.js linguist-vendored 4 - web/static/js/htmx.min.js linguist-vendored 3 + static/js/alpine.min.js linguist-vendored 4 + static/js/htmx.min.js linguist-vendored 5 5
+1 -1
.gitignore
··· 17 17 *.out 18 18 19 19 # Generated files 20 - web/static/css/output.css 20 + static/css/output.css 21 21 22 22 # Database 23 23 *.db
+3 -10
CLAUDE.md
··· 8 8 Add proper styling to mail link and 'back to home' button on terms page. 9 9 10 10 Acceptance criteria: 11 + 11 12 - Consistent button/link styling 12 13 - Matches site design system 13 14 - Good visual hierarchy ··· 15 16 ## Completion Instructions 16 17 17 18 When you have completed this task: 19 + 18 20 1. Ensure all work is committed and ready to merge 19 21 2. Exit the session - you'll be prompted to complete, keep, or reopen the cell 20 22 ··· 103 105 routing/ 104 106 routing.go # Router setup and middleware chain 105 107 lexicons/ # AT Protocol lexicon definitions (JSON) 106 - web/static/ # CSS, JS, manifest 108 + static/ # CSS, JS, manifest 107 109 ``` 108 110 109 111 ## Key Concepts ··· 681 683 ``` 682 684 683 685 This is automatically handled by the build process, but you may need to run it manually during development. 684 - 685 - ## Known Issues / TODOs 686 - 687 - Key areas: 688 - 689 - - Context should flow through methods (some fixed, verify all paths) 690 - - Cache race conditions need copy-on-write pattern 691 - - Missing CID validation on record updates (AT Protocol best practice) 692 - - Rate limiting for PDS calls not implemented
+2 -2
default.nix
··· 9 9 nativeBuildInputs = [ templ tailwindcss ]; 10 10 11 11 preBuild = '' 12 - tailwindcss -i web/static/css/app.css -o web/static/css/output.css --minify 12 + tailwindcss -i static/css/app.css -o static/css/output.css --minify 13 13 templ generate 14 14 ''; 15 15 ··· 41 41 mkdir -p $out/share/arabica 42 42 43 43 # Copy static files 44 - cp -r web $out/share/arabica/ 44 + cp -r static $out/share/arabica/ 45 45 cp arabica $out/bin/arabica-unwrapped 46 46 cat > $out/bin/arabica <<'WRAPPER' 47 47 ${wrapperScript}
+1 -1
deploy/Dockerfile
··· 34 34 COPY --from=builder /app/arabica . 35 35 36 36 # Copy static assets 37 - COPY --chown=arabica:arabica web/static/ ./web/static/ 37 + COPY --chown=arabica:arabica static/ ./static/ 38 38 39 39 # Note: Templ components are compiled into the binary, no need to copy .templ files 40 40
+1 -1
flake.nix
··· 26 26 type = "app"; 27 27 program = toString (pkgs.writeShellScript "tailwind-build" '' 28 28 cd ${./.} 29 - ${pkgs.tailwindcss}/bin/tailwindcss -i web/static/css/app.css -o web/static/css/output.css --minify 29 + ${pkgs.tailwindcss}/bin/tailwindcss -i static/css/app.css -o static/css/output.css --minify 30 30 ''); 31 31 }; 32 32 });
+1 -1
internal/routing/routing.go
··· 95 95 mux.HandleFunc("GET /profile/{actor}", h.HandleProfile) 96 96 97 97 // Static files (must come after specific routes) 98 - fs := http.FileServer(http.Dir("web/static")) 98 + fs := http.FileServer(http.Dir("static")) 99 99 mux.Handle("GET /static/", http.StripPrefix("/static/", fs)) 100 100 101 101 // Catch-all 404 handler - must be last, catches any unmatched routes
+1 -1
justfile
··· 14 14 @go test ./... -cover -coverprofile=cover.out 15 15 16 16 style: 17 - @nix develop --command tailwindcss -i web/static/css/app.css -o web/static/css/output.css --minify 17 + @nix develop --command tailwindcss -i static/css/app.css -o static/css/output.css --minify
web/static/arabica-org.png static/arabica-org.png
web/static/css/app.css static/css/app.css
web/static/favicon-32.svg static/favicon-32.svg
web/static/favicon.svg static/favicon.svg
web/static/icon-192.svg static/icon-192.svg
web/static/icon-512.svg static/icon-512.svg
web/static/icon-placeholder.svg static/icon-placeholder.svg
web/static/js/alpine.min.js static/js/alpine.min.js
web/static/js/brew-form.js static/js/brew-form.js
web/static/js/data-cache.js static/js/data-cache.js
web/static/js/dropdown-manager.js static/js/dropdown-manager.js
web/static/js/entity-helpers.js static/js/entity-helpers.js
web/static/js/entity-manager.js static/js/entity-manager.js
web/static/js/handle-autocomplete.js static/js/handle-autocomplete.js
web/static/js/htmx.min.js static/js/htmx.min.js
web/static/js/manage-page.js static/js/manage-page.js
web/static/js/profile-stats.js static/js/profile-stats.js
web/static/js/sw-register.js static/js/sw-register.js
web/static/js/transitions.js static/js/transitions.js
web/static/manifest.json static/manifest.json
web/static/service-worker.js static/service-worker.js