A:\compassion-rescueIn Progress — staging delivered

in progress eject· back to the shelf

Bilingual · Full-StackAnimal Rescue

Compassion Rescue

A bilingual public site, adoption pipeline, and shelter operations platform for an animal rescue organization.

May – June 2026 ~6 Weeks to Staging

COMPASSION RESCUE

Where Every Life Is Curated With Compassion

Languages, EN / ZH
2
Programs Unified
4
Epics Shipped
7/7
Residents directory
Client
Compassion Rescue
Industry
Animal Rescue · Nonprofit
Engagement
Full-stack platform build
Status
In Progress — staging delivered
Duration
May – June 2026 · ~6 weeks to staging
Scope
Bilingual public site, admin platform, volunteer portal

01 Overview

Who is the client?

Compassion Rescue is an animal shelter serving a bilingual community — the platform runs fully in English and Simplified Chinese, and the shelter's own default settings for language, timezone, and currency point to a Chinese-speaking operation. Their work spans four programs: adopting animals out to permanent homes, placing animals with foster carers, running a volunteer program with scheduled shifts, and publishing news and success stories to keep the community engaged.

02 Problem Statement

What problem were they facing?

The shelter was running all of this without a system — no public catalogue, no application pipeline, no volunteer portal, and no way to touch content without a developer, in two languages.

  1. No public catalogue

    Someone wanting to adopt had no way to browse who was available, filter by type or age or size, or read an animal's story and medical background before reaching out.

  2. No application pipeline

    Adoption, foster, and volunteer applications had no intake process and no pipeline behind them. Tracking pending vs. approved was manual — and remembering to update the animal's availability once an adoption went through was exactly the kind of thing that slips.

  3. No volunteer portal

    Shifts, announcements, and logged hours lived wherever the coordinator kept them, with no self-serve system for volunteers to check either.

  4. Developer required for every change, in two languages

    News posts, the animals themselves, site announcements — everything content-related needed technical help to change, doubled by the bilingual requirement.

03 Solution

How did we solve it?

We built a full platform around the four programs, with the bilingual requirement treated as a first-class constraint rather than an afterthought. The public site covers the whole visitor journey — homepage, a filterable residents directory with URL-synced filters, animal detail pages, and news with individual articles. Every piece of text, including animal descriptions, exists in both English and Chinese, with a language toggle that remembers the visitor's choice and its own CJK typography rules — no italics, no letter-spacing.

Applying is a proper multi-step flow, separate for adoption, foster, and volunteer, with drafts saved as the applicant types. The admin side is where the operational value sits: a dashboard, full animal management, a bilingual content editor, foster and volunteer management with shift scheduling, medical records per animal, site settings, and an adoption pipeline where applications move pending → reviewing → approved/rejected with a confirmation dialog and a five-second undo on every action. The piece that ties it together is a backend hook — when an adoption is approved, the animal's status flips to "adopted" automatically, and a foster approval flips it to "pending".

  1. FE Next.js 16 Bilingual frontend React 19Cookie auth
  2. PB PocketBase Go + embedded SQLite Custom seed cmdApproval hook
  3. S3 MinIO Object storage Auto-provisionedS3-compatible
One PocketBase binary · embedded SQLite · Dockerized end-to-end on Dokploy
  • Next.js 16
  • React 19
  • TypeScript
  • PocketBase
  • Go
  • SQLite
  • MinIO (S3)
  • Tailwind CSS v4
  • Docker
  • Dokploy

Live on staging — real screens, real seeded data

Animal detail page
Animal Detail
Adoption application flow
Adoption Apply

04 Project Timeline

Key milestones and duration

  1. Phase 1 May 4–15, 2026

    Foundation & Public Site

    Project structure, Docker environments, the design system, and the public pages built against mock data with "coming soon" markers on anything not yet wired.

  2. Phase 2 May 11–18, 2026

    Backend & Schema

    PocketBase collections for animals, applications, posts, volunteers, shifts, fosters, medical records, and settings, defined in code with per-collection access rules. Seed data in both languages.

  3. Phase 3 May 19–25, 2026

    Staging Infrastructure

    The Dokploy deployment, MinIO storage wiring, and a written operator runbook. Two permanent gotchas documented here: build-time env vars, and Dokploy's single-compose-file requirement.

  4. Phase 4 June 8–12, 2026

    Live Backend Integration

    A written plan — including an upfront adversarial review that caught an SDK version mismatch, missing update rules, and a settings anti-pattern — followed by wiring every screen to the live backend and removing every mock banner.

  5. Phase 5 June 12–16, 2026

    Systematic QA

    An accessibility + interaction audit and a five-state resilience check (loading, error, empty, sparse, full) applied to every data-fetching point. Every item checked off, smoke tests pass, build is clean.

  6. Production Rollout From June 17, 2026 — In Progress

    Domain & Storage Migration

    Staging verified and signed off. The rollout plan covers domain and DNS, moving object storage from MinIO to a cloud provider, backup retention, and a final security review.

05 Challenges & Resolutions

What obstacles did we face, and how did we overcome them?

  1. Server renders English, browser remembers Chinese

    problemThe saved language lives in the browser, but the server renders first — so a returning Chinese-language visitor could see the page flash English before switching. Distracting on every single navigation.

    resolutionThe language provider now waits until the client has confirmed the saved language before rendering, behind a neutral loading state — no flash, no flicker, on any page.

  2. Approved adoption, stale listing

    problemApproving an adoption used to require remembering a second step: going back and marking the animal unavailable. That's exactly the kind of manual step that gets forgotten under real workload.

    resolutionA backend hook closed the gap — approval and the animal's status change are now one action, running server-side, so it works no matter which screen or client triggered the approval.

  3. A production build that broke in a way dev never would

    problemNEXT_PUBLIC_ environment variables get compiled into the JavaScript bundle at build time — changing them on the server and restarting does nothing. Cost real debugging time on staging: login worked, every admin page said "failed to fetch".

    resolutionGot a permanent note in the repo, and the runbook now includes a one-line command to verify the URL actually made it into the built bundle before anyone chases a phantom bug again.

  4. Image uploads succeeded, then 404'd

    problemPocketBase won't use S3 storage until it's explicitly told to. On a fresh deploy, uploads would appear to succeed and then 404 — silent until someone actually clicked the image.

    resolutionA scripted one-time step (npm run configure-s3) went into the first-deploy bootstrap checklist and is documented as the canonical first-deploy gotcha.

  5. Backend written against an API newer than the pinned version

    problemThe backend was initially written against a newer PocketBase API than the version actually pinned in the module file — it didn't compile.

    resolutionThe adversarial review built into the integration plan caught it before it could block anything downstream; the backend was refactored to the correct SDK surface before wiring began.

06 Before & After

Comparison of the situation before and after the project

BeforeAfter
No public catalogue of animals in careFilterable bilingual directory with detail pages and shareable, URL-synced filtered views
No formal intake for adoption, foster, or volunteer interestMulti-step adoption/foster/volunteer flows with draft saving as the applicant types
Application tracking done manuallyPipeline with statuses, search, confirmation dialogs, rejection reasons, and a five-second undo
Adoption → listing update was a separate manual step, easy to missAutomatic via a backend hook — approval and availability change in one action
No volunteer system — shifts and hours lived wherever the coordinator kept themAuthenticated portal with shifts, announcements, logged hours; admin-side scheduling
Medical history not digitizedPer-animal medical records in the admin panel
Developer needed for every content change, single languageBilingual editor, news publishing, announcement banner — all self-serve
No deployment infrastructureDockerized stack on Dokploy with S3 storage, health checks, backups, and an operator runbook
Adoption pipeline board
The adoption pipeline — pending → reviewing → approved/rejected, with a confirmation dialog before every status change and a five-second undo after.

07 Client Benefits & Outcomes

What value did the client gain?

Epics Shipped
7/7
all tasks complete, mock banners removed
Languages
2
English · Simplified Chinese, hydration-safe
Programs Unified
4
adopt · foster · volunteer · news
Resilience States Audited
5
loading · error · empty · sparse · full
  • One system instead of scattered manual processes

    Staff manage animals, applications, fosters, volunteers, medical records, and content themselves, in both languages, without technical help.

  • The two most damaging failure modes of manual tracking are gone

    Every application has a status someone owns, and an approved adoption updates the public site by itself — lost applications and stale listings can't happen anymore.

  • A genuinely accessible front door

    44px touch targets, focus traps in modals, skip-to-content, zero layout shift, ARIA roles — the audit standards weren't aspirational, they were verified item by item.

  • A documented, reproducible system sized to a nonprofit's budget

    One backend binary, one modest server, open-source object storage locally with a clear upgrade path to cloud storage for production. The runbook means a fresh deploy doesn't depend on whoever set it up being available.

Admin dashboard
The admin dashboard — pending applications, recent activity, and a long-stay alert surfaced automatically. Rendered here in the shelter's own default language, Simplified Chinese.

08 Key Learnings & Takeaways

What did we learn from this project?

  1. Writing failure modes down before building catches real bugs

    The adversarial review in the integration plan found a broken SDK version, missing access rules, and a schema anti-pattern before any of them cost debugging time downstream. A cheap habit with a high hit rate.

  2. Checklists beat memory for QA at this scale

    "Does every fetch point handle loading, error, empty, sparse, and full?" isn't a question anyone answers reliably from memory across forty-plus screens. Two audit documents with per-item checkboxes made the verification real instead of assumed.

  3. Deployment gotchas belong in the repo, not in someone's head

    The build-time env var issue and the S3 configuration step each burned time once; both are now permanent notes with verification commands, and neither can burn time twice.

  4. Internationalization is a design constraint, not a translation task

    Duplicated content fields, CJK typography rules, hydration-safe language detection — all of it had to be decided early, because retrofitting any of it would have touched every screen.

  5. Automate the step humans forget

    The adoption-approval hook is ten lines of backend code that eliminates the single most likely operational error in the whole workflow.

Live on staging · Real seeded data

The Modules

Every screen maps to a real workflow the shelter operates daily, captured live off the running staging build. Click any to expand.

Homepage
Homepage Latest arrivals, spotlight animal, recent news
Homepage (中文)
Homepage (中文) Full Simplified Chinese, CJK typography rules applied
Residents Directory
Residents Directory Filterable by type, age, size, status — URL-synced
Animal Detail
Animal Detail Story, medical background, apply-to-adopt CTA
News & Stories
News & Stories Success stories, events, and shelter news
Adopt: Apply
Adopt: Apply Multi-step adoption flow with draft saving
Volunteer: Apply
Volunteer: Apply Multi-step volunteer intake flow
Staff Login
Staff Login Cookie-authenticated entry point to the admin hub
Admin Dashboard
Admin Dashboard Applications, recent activity, long-stay alerts
Animal Management
Animal Management Full CRUD across every resident, status and intake tracking
Adoption Pipeline
Adoption Pipeline Pending → reviewing → approved/rejected board
Content Editor
Content Editor Bilingual news and success-story publishing
Volunteer Management
Volunteer Management Application queue, roster, expertise, and status
Foster Management
Foster Management Carers, active placements, and waiting list
Medical Records
Medical Records Per-animal vaccination, surgery, and checkup history
Site Settings
Site Settings Branding, announcement banner — shown in the shelter's default language
Volunteer Portal
Volunteer Portal Shifts, announcements, and logged hours
disk label
Compassion Rescue's own palette and type
ground
[TBD]
accent
#2E7A4A
soft
#52B788
ink
[TBD]
mat (sampled from its screens)
#F8F6F5
type
[TBD]