ginnoir
4ea9b86f8e
chore: release v0.6.10
CI / checks (push) Skipped
Release Image / build-and-push (push) Successful in 7m45s
2026-07-18 17:25:59 -05:00
ginnoir
0be93d088b
chore: release v0.6.9
CI / checks (push) Skipped
Release Image / build-and-push (push) Successful in 8m21s
2026-07-18 17:23:06 -05:00
ginnoir
d1e295165a
chore: release v0.6.8
CI / checks (push) Skipped
Release Image / build-and-push (push) Successful in 9m8s
2026-07-18 17:19:56 -05:00
ginnoir
908764873f
chore: release v0.6.7
CI / checks (push) Has been skipped
Release Image / build-and-push (push) Successful in 7m37s
2026-07-12 22:28:20 -05:00
ginnoir
3efbf75179
chore: release v0.6.6
CI / checks (push) Has been skipped
Release Image / build-and-push (push) Successful in 7m7s
2026-07-12 22:18:50 -05:00
ginnoir
7bf4a801b3
chore: release v0.6.5
CI / checks (push) Has been skipped
Release Image / build-and-push (push) Successful in 7m19s
2026-07-09 00:38:50 -05:00
ginnoir
60eb101015
chore: release v0.6.4
CI / checks (push) Has been skipped
Release Image / build-and-push (push) Successful in 7m30s
2026-07-08 22:51:47 -05:00
ginnoir
9bf8e508c7
chore: release v0.6.3
CI / checks (push) Has been skipped
Release Image / build-and-push (push) Successful in 8m55s
2026-07-08 21:41:06 -05:00
ginnoir
ea371b8085
chore: release v0.6.2
CI / checks (push) Has been skipped
Release Image / build-and-push (push) Successful in 9m6s
2026-07-08 20:46:44 -05:00
ginnoir
3a5c6d056c
chore: release v0.6.1
CI / checks (push) Has been skipped
Release Image / build-and-push (push) Failing after 45s
2026-07-05 02:02:07 -05:00
ginnoir
a58a91d8b8
chore: release v0.6.0
CI / checks (push) Failing after 3m1s
CI / build (push) Successful in 5m17s
Release Image / build-and-push (push) Successful in 6m32s
2026-07-04 23:26:40 -05:00
ginnoir
fd338384b7
chore: release v0.5.6
CI / checks (push) Failing after 2m11s
CI / build (push) Successful in 4m41s
Release Image / build-and-push (push) Successful in 6m22s
2026-07-04 22:43:01 -05:00
ginnoir
9d13d6a430
chore: release v0.5.5
CI / checks (push) Failing after 2m11s
CI / build (push) Successful in 4m40s
Release Image / build-and-push (push) Failing after 4m8s
2026-07-04 22:40:11 -05:00
ginnoir
060a2f19a9
chore: release v0.5.4
CI / checks (push) Failing after 2m12s
CI / build (push) Successful in 4m39s
2026-07-04 22:39:45 -05:00
ginnoir
04ae809e07
feat(journal): add per-user mood journal module (task 86)
...
Ship journal entries with mood tracking, insights, and Recharts charts.
Adds v1 API endpoints per ADR 0005 and migration 0020_journal_entries.
2026-07-04 19:41:15 -05:00
ginnoir
a4be5d5061
feat(notes): rich-text editor with tiptap (task 85)
...
Replace plain textarea with shared tiptap editor and sanitized html rendering.
Adds interactive checklists on read surfaces and mobile overflow fixes.
2026-07-04 19:25:15 -05:00
ginnoir
55b0e68b35
feat(shadcn): install 10 missing components
2026-06-13 03:08:56 -05:00
ginnoir
615d9c9377
fix: declare unlisted dependencies surfaced by knip
...
CI / checks (push) Has been cancelled
CI / build (push) Has been cancelled
sharp (icon script), @auth/core (adapter types in _core/schema),
react-resizable (css imported by dashboard-editor), and server-only
were imported but undeclared, resolving only via pnpm hoisting.
2026-06-09 15:55:36 -05:00
ginnoir
a12208d2fe
chore: release v0.5.3
Release / build-and-push (push) Has been cancelled
2026-06-03 20:18:21 -05:00
ginnoir
c3e78932fe
chore: release v0.5.2
Release / build-and-push (push) Has been cancelled
2026-06-03 20:06:55 -05:00
ginnoir
51c8d3c92d
chore: release v0.5.1
Release / build-and-push (push) Has been cancelled
2026-06-03 19:55:57 -05:00
ginnoir
2408d37f8e
chore: release v0.5.0
Release / build-and-push (push) Has been cancelled
2026-06-03 19:20:37 -05:00
ginnoir
6e92648a41
feat: mobile experience overhaul — touch targets, calendar mobile layout, swipe gestures
2026-06-03 18:50:15 -05:00
ginnoir
6802ae08db
fix: db:seed script points to seed.mjs not nonexistent seed.ts
2026-06-03 16:19:29 -05:00
ginnoir
b935ff209c
chore: release v0.4.10
Release / build-and-push (push) Has been cancelled
2026-06-03 16:16:01 -05:00
ginnoir
3fb5ddc5dd
chore: upgrade node 22 to 24 lts
2026-06-03 16:15:00 -05:00
ginnoir
ca536b5c33
chore: release v0.4.9
Release / build-and-push (push) Has been cancelled
2026-06-03 16:00:38 -05:00
ginnoir
10cad3df17
chore: release v0.4.8
Release / build-and-push (push) Has been cancelled
2026-06-02 20:26:57 -05:00
ginnoir
31c5805b34
chore: release v0.4.7
2026-06-02 18:30:48 -05:00
ginnoir
090366422d
chore: release v0.4.6
Release / build-and-push (push) Has been cancelled
2026-06-02 18:16:26 -05:00
ginnoir
272d3cbbe6
chore: release v0.4.5
Release / build-and-push (push) Has been cancelled
2026-06-02 04:27:39 -05:00
ginnoir
b5a966e3a9
feat(bangs): add bang counter dashboard widget
...
Adds a new "bangs" module with a dashboard widget that tracks household
bang events. The widget shows the total count, a configurable recent-bang
list, and an "Add Bang" button that accepts a backdatable date.
On submission, a full celebration sequence fires: screen flash, widget
shake, count pop animation, synthesized firework sound (Web Audio API),
50 full-screen emoji particles via portal, canvas-confetti star bursts,
side cannons, and a timed sequence of 7 firework bursts.
- New bang_events table (migration 0017)
- canvas-confetti dependency for fireworks/confetti effects
- CSS keyframe animations: shake, countPop, emojiFloat
- Fixes pre-existing Drizzle snapshot chain collision (0007/0008)
- Adds OpenPlantBook env vars to compose.yaml
2026-06-02 04:26:22 -05:00
ginnoir
48063e4b7f
chore: release v0.4.4
Release / build-and-push (push) Has been cancelled
2026-06-02 03:48:52 -05:00
ginnoir
7d0f02996f
chore: release v0.4.3
Release / build-and-push (push) Has been cancelled
2026-06-02 03:25:03 -05:00
ginnoir
e0b423aad5
chore: remove dead code and unused dependencies
...
- Delete src/placeholder.ts (empty stub with no references)
- Remove zod-to-json-schema dep (not imported anywhere in src/)
- Remove @eslint/eslintrc devDep (project uses flat config with @eslint/js)
- Remove @types/react-grid-layout devDep (react-grid-layout v2 ships own types)
2026-06-02 02:37:56 -05:00
ginnoir
65d36bab4e
fix: drive bottom nav from module registry so all modules appear on mobile
...
Release / build-and-push (push) Has been cancelled
The bottom nav was hardcoded; the sidebar already read from the module
registry. Converted BottomNav to a server component that calls
getRegistry() using the same pattern as Sidebar, so any module with a
nav field automatically populates both nav surfaces.
Bumps version to 0.4.2.
2026-06-02 01:55:36 -05:00
ginnoir
6d45b7e836
chore: bump version to 0.4.0
Release / build-and-push (push) Has been cancelled
2026-06-02 00:00:03 -05:00
ginnoir
2fd0677c5f
feat: add garden module infrastructure (task 70)
...
- Add MinIO service to compose.yaml with named volume
- Add generic /api/uploads POST+GET route with auth, 5 MB, image/* guards
- Add src/lib/minio.ts singleton client with ensureBucket helper
- Add garden Drizzle schema: containers, plants, care_logs, care_schedules, species_cache
- Register garden module in src/modules/index.ts and src/lib/db.ts
- Apply migration 0015_garden_schema.sql
- Add MINIO_* and PERENUAL_API_KEY to .env.example
- Add task briefs 70-75 for the full garden feature arc
- Add uploads.spec.ts E2E test (RED → GREEN on route auth guard)
2026-06-01 19:23:19 -05:00
ginnoir
8921cb0444
chore: release v0.3.0
Release / build-and-push (push) Has been cancelled
2026-06-01 18:43:13 -05:00
ginnoir
e3d2b5a364
chore: sync version to v0.2.0 and load .env for release scripts
2026-06-01 18:41:32 -05:00
ginnoir
30af9f63bf
chore: add release workflow (commitlint, husky, lint-staged, release-it)
2026-06-01 18:33:37 -05:00
ginnoir
19308be768
feat: add dev startup script, fix push notifications, and scope test sends to device
...
- pnpm dev:local/dev:reset: orchestrate DB container, migrations, seed, and Next.js dev server in one command; Caddy snippet + docs for HTTPS via dev.ginnoir.com
- Fix dev login on HTTPS: set both authjs.session-token and __Secure-authjs.session-token so Auth.js finds the session regardless of cookie name resolution
- Suppress hydration mismatch on <html> caused by pre-paint script changing data-nav before React hydrates
- VAPID startup warning if keys not configured; remove dead NEXT_PUBLIC_VAPID_PUBLIC_KEY var
- PushOptIn: hydrate subscription state on mount; reuse existing subscription on iOS to avoid redundant prompts
- sendPushToEndpoint: new function to send to a single device endpoint
- sendTestNotification: scoped to the calling device's endpoint (ownership-verified) instead of all user subscriptions
2026-06-01 17:45:20 -05:00
ginnoir and Claude Sonnet 4.6
285a460eb8
Implement tasks 60, 61, 62: backups, rate limiting, structured logging
...
Task 60 — Postgres backups:
- deploy/backups/: backup.sh (pg_dump -Fc nightly), retain.sh (14/8/6 tiers),
restore.sh, entrypoint.sh, crontab
- famapp-backup Alpine service + backups volume added to deploy/compose.yaml
- Restore procedure in deploy/backups/README.md
Task 61 — Rate limiting on share links:
- src/lib/rate-limit.ts: Edge-compatible sliding-window counter (50/min, LRU eviction)
with consume(), isRateLimited(), recordFailure() exports
- middleware.ts: enforces 429 with Retry-After: 60 for /s/[token] (IP + token prefix)
- /s/[token]/page.tsx: tracks only failed resolveShareToken calls via recordFailure()
Task 62 — Structured logging:
- pino + pino-pretty installed; serverExternalPackages added to next.config.ts
- src/lib/logger.ts: JSON in production, pretty in dev, level from LOG_LEVEL env
- middleware.ts: structured JSON request log (method, path, status, ms, authenticated)
- _core/push.ts, notify.ts, reminders.ts: console.error/log → logger.error/info
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 17:23:29 -05:00
ginnoir and Claude Sonnet 4.6
b6abe052c9
Implement tasks 40, 41, 42: web push, notification bus, reminders engine
...
Task 40 — Web Push (VAPID):
- Add web-push package + @types/web-push
- pnpm vapid:generate script prints VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, NEXT_PUBLIC_VAPID_PUBLIC_KEY
- push_subscriptions schema + migration 0013
- _core/push.ts: sendPush() iterates subscriptions, prunes 404/410 stale entries
- SW push/notificationclick event handlers added to generated sw.js template
- PushOptIn client component on /settings (opt-in, disable, send test)
Task 42 — Notification bus + ntfy adapter:
- notifications table + notif_push/notif_inapp/notif_ntfy user columns (migration 0013)
- _core/notify.ts: notify() fans out to push, in-app DB, and optional ntfy POST
- NotificationBell server component in AppNav: unread badge, dropdown inbox, mark-read
- NotifyChannelToggles client component in /settings
Task 41 — Reminders engine:
- fired_at + created_by added to reminders; default channel changed to 'auto'
- _core/reminders.ts: scheduleReminder (upsert), cancelReminder, listReminders, tickReminders
- tickReminders uses pg_try_advisory_xact_lock for horizontal-scale safety
- src/instrumentation.ts starts reminder worker (30s tick) on Node.js boot
- Notes actions use scheduleReminder/cancelReminder instead of raw SQL
- Calendar createEvent: optional remindMinutesBefore, deleteEvent: cancelReminder
- Calendar-shell: "Remind me 30 min before" checkbox on new event form
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 16:55:02 -05:00
ginnoir and Claude Sonnet 4.6
8aab25e0ac
Implement PWA shell (task 50)
...
Add web manifest, placeholder icons, app-shell service worker, and
install prompt so famapp is installable on iOS and Android home screens.
- public/manifest.webmanifest — name, short_name, standalone display,
start_url /, all four icon sizes (192/384/512 + maskable)
- public/icon-{180,192,384,512,512-maskable}.png — indigo placeholder
squares generated by scripts/generate-icons.mjs (pnpm gen:icons)
- public/icon.svg — house-icon SVG source for future branded export
- public/sw.js — hand-rolled app-shell SW: precaches offline.html,
cache-first for /_next/static/, network-first navigation with offline
fallback, network-only for /api/*
- public/offline.html — branded offline fallback page
- src/components/pwa-register.tsx — client SW registration
- src/components/install-prompt.tsx — dismissible install banner:
beforeinstallprompt on Android, "Add to Home Screen" hint on iOS
- Root layout: viewport themeColor, manifest/appleWebApp metadata,
apple-touch-icon, mounts PwaRegister + InstallPrompt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 16:00:02 -05:00
ginnoir and Claude Sonnet 4.6
d5a8bf9d95
Implement tasks 25, 26 + completion visibility setting
...
Task 25: Multiple dashboards — dashboards table + migration, /d/[slug]
route, root redirect, dashboard tabs in nav with create/rename/delete/
set-default. Task 26: Editable dashboard — react-grid-layout drag/resize
editor, widget picker modal with per-widget configurator auto-generated
from default config, save/reset server actions with Zod validation.
Completion visibility: server-side per-user setting (hours) replaces
localStorage timer; queries filter completed items by updatedAt cutoff;
Settings page dropdown persists preference via server action.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 15:52:59 -05:00
ginnoir and Claude Sonnet 4.6
1133fa8aac
Implement quick-add registry (task 21)
...
- Add url field to QuickAddAction; make action optional
- Add getQuickAdds() + SerializedQuickAddItem to registry so quick-add
data can cross the server→client RSC boundary without serializing fns
- Update calendar/lists/notes manifests with navigation URLs
- QuickAddProvider wraps root layout: holds sheet/palette open state and
global cmd/ctrl+k shortcut
- QuickAddSheet: bottom drawer on mobile, right-side popover on desktop,
actions grouped by module
- CommandPalette: cmdk-powered modal with fuzzy filter and full keyboard
nav (arrows + enter + esc)
- QuickAddFab: client button replacing the plain + stub in the dashboard
- Add .claude/** to ESLint ignores to prevent stale worktree artifacts
from failing lint
All 4 E2E specs pass; typecheck, lint, and build clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 13:44:33 -05:00
ginnoir
744c1119a9
Implement calendar module
2026-05-06 03:10:28 -05:00
ginnoir and Claude Sonnet 4.6
6710c8b231
Add household seeding & session (task 07)
...
- scripts/seed.ts: idempotent pnpm db:seed inserts "Home" household if none exists (powered by tsx)
- signIn callback: first member of household gets owner role, subsequent users get member
- src/lib/session.ts: getCurrentSession() returns { user, household, role }, throws if unauthenticated or unmembered
- /settings/household: member list for all roles; rename form gated to owner only (server action also enforces)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 02:42:48 -05:00
ginnoir and Claude Sonnet 4.6
5da472d6ff
Add Authentik OIDC integration (task 06)
...
- next-auth@beta + @auth/drizzle-adapter wired up with database sessions
- src/lib/auth.ts: OIDC provider, authorized callback, signIn household-attach, getCurrentUser()
- src/middleware.ts: protects all routes except /login, /s/*, /api/auth/*
- src/app/api/auth/[...nextauth]/route.ts: mounts Auth.js handlers
- src/app/login/page.tsx: single SSO sign-in button (server action)
- Schema: users extended (name/emailVerified/image), accounts/sessions/verificationTokens added
- drizzle/0001_auth_tables.sql: migration for schema changes
- deploy/authentik/README.md: manual bootstrap steps for Authentik
- src/lib/db.ts: pass schema to drizzle for relational query builder
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 02:37:41 -05:00