https://github.com/robbdimitrov/phasma
Modern image-sharing application delivering real-time visual feeds via responsive Svelte and a high-performance Go API.
https://github.com/robbdimitrov/phasma
docker golang javascript kubernetes svelte typescript
Last synced: about 17 hours ago
JSON representation
Modern image-sharing application delivering real-time visual feeds via responsive Svelte and a high-performance Go API.
- Host: GitHub
- URL: https://github.com/robbdimitrov/phasma
- Owner: robbdimitrov
- License: mit
- Created: 2017-10-24T10:58:22.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2026-07-10T17:49:43.000Z (4 days ago)
- Last Synced: 2026-07-10T19:15:53.651Z (4 days ago)
- Topics: docker, golang, javascript, kubernetes, svelte, typescript
- Language: Go
- Homepage:
- Size: 8.66 MB
- Stars: 10
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Security: docs/security.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Phasma
**Phasma** is a full-stack image-sharing platform built with a production-grade
architecture. Combining a robust Go API with a modern SvelteKit frontend, it
provides a seamless experience for users to upload, browse, and interact with
images.

## Features
- **Image sharing**: Upload, browse, like, and comment on images with a
responsive feed and profile pages.
- **Social feed**: Personalized feed of posts from followed users,
pre-materialized on write by a Kafka consumer group (fan-out on follow/post).
- **Notifications**: Real-time like, comment, and follow notifications with
unread badge and mark-as-read support.
- **Rich text**: Captions, comments, and bios render `@mention`, `#hashtag`, and
URL links. Compose typeahead suggests users and hashtags as you type.
- **Global search**: Search users, posts, and hashtags with paginated results. A
leading `#` scopes results to hashtag-filtered posts.
- **Object storage**: Image bytes are stored in SeaweedFS (S3-compatible),
decoupled from the database and served with `Cache-Control` and `ETag`
headers.
- **Cache layer**: Dragonfly (Redis-protocol) backs rate-limit token buckets and
login-failure counters, keeping the hot path off PostgreSQL.
- **Event streaming**: Every domain mutation writes to a transactional outbox.
The backend relay polls unpublished rows, publishes to Redpanda
(Kafka-compatible) topics, then marks the rows published. The topics are
consumed by the notifications and feed workers and the Meilisearch sync
pipeline.
- **Session management**: Argon2id password hashing, HMAC-keyed session tokens,
per-user session listing and remote revocation.
- **Production-ready**: Stateless Go API, bounded concurrency, absolute session
lifetimes, dependency-aware readiness probe, structured JSON logging, circuit
breaker and retry-with-backoff on every database call.
- **HA-ready**: Ships at `replicas: 1` but correct at `replicas: N`. No shared
in-process state; outbox delivery is at least once and all consumers use
idempotent inserts with `ON CONFLICT DO NOTHING`.
## Architecture
```mermaid
graph TD
Browser["Browser"]
subgraph cluster ["Kubernetes Cluster"]
Frontend["Frontend
(SvelteKit)"]:::frontend
Gateway["Backend
(Go)"]:::backend
subgraph data ["Data & Storage"]
DB[("PostgreSQL
(source of truth)")]:::database
Search[("Meilisearch
(search index)")]:::search
end
end
Browser --> Frontend
Frontend --> Gateway
Gateway --> DB & Search
classDef frontend fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
classDef backend fill:#6366f1,stroke:#4f46e5,stroke-width:2px,color:#fff
classDef database fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#fff
classDef search fill:#06b6d4,stroke:#0891b2,stroke-width:2px,color:#fff
style cluster fill:transparent,stroke:#64748b
style data fill:transparent,stroke:transparent
```
| Service | Language | Description |
| -------------------------- | ---------- | -------------------------------------------------------------- |
| [frontend](/apps/frontend) | TypeScript | SvelteKit SSR application; sole public entry point and BFF. |
| [backend](/apps/backend) | Go | HTTP API handling users, sessions, images, likes, and uploads. |
| [database](/apps/database) | PostgreSQL | Versioned schema migrations managed by `migrate/migrate`. |
### Infrastructure
Six in-cluster services run alongside the application:
- **PostgreSQL** — Primary source of truth for all application data.
- **Dragonfly** — Redis-protocol cache backing rate-limit token buckets and
login-failure counters. The API fails open on unavailability.
- **SeaweedFS** — S3-compatible object store holding image bytes. The API
streams blobs directly; no image data touches PostgreSQL.
- **Meilisearch** — Derived search index. PostgreSQL is the only source of
truth; Meilisearch is populated and kept current via the Redpanda outbox
pipeline.
- **Redpanda** — Kafka-compatible event broker. Receives `entity-changes` and
`activity` events published by the backend outbox relay; consumed by
Redpanda Connect and the backend's
`notifications-consumer` and `feed-consumer` goroutines.
- **Redpanda Connect** — Stateless Kafka consumer for Meilisearch sync plus a
one-shot backfill job for users, posts, and hashtags.
## Docs
Architectural specs live in [`docs/`](/docs/):
| Doc | Contents |
| -------------------------------------------- | -------------------------------------------------------------- |
| [architecture.md](/docs/architecture.md) | Service topology, request flow, integration patterns |
| [api.md](/docs/api.md) | HTTP endpoints, middleware stack, pagination |
| [data-model.md](/docs/data-model.md) | Schema, indexes, entity relationships, domain invariants |
| [security.md](/docs/security.md) | Session model, password policy, ownership rules, rate limiting |
| [business-rules.md](/docs/business-rules.md) | Validation constraints, ordering, content policy |
| [frontend.md](/docs/frontend.md) | Route map, layout hierarchy, SSR, data fetching |
| [design-system.md](/docs/design-system.md) | Theme, component inventory, layout |
| [infrastructure.md](/docs/infrastructure.md) | Kubernetes resources, secrets, probes, storage |
## Deploy
Deploy the application to your active Kubernetes cluster using the provided
script:
```sh
./scripts/deploy.sh
```
The script builds the Docker images, creates the Kubernetes namespace (`phasma`
by default) and resources, waits for pods to be ready, and starts a port-forward
to the frontend at http://localhost:8080/. It is idempotent and safe to re-run
for updates.
## Cleanup
To remove all deployed resources and the namespace:
```sh
kubectl delete -f ./deploy -n phasma
kubectl delete namespace phasma
```
## Testing
Run all unit tests across the frontend and backend:
```sh
make test
```
## License
Licensed under the [MIT](LICENSE) License.