Skip to content

miratcan/Resmin

Repository files navigation

peeka.pics

Photo Q&A platform — someone asks a question with a photo, others answer with their own.

peeka.pics is a community where members open questions and answer with photos of their own. Live at https://peeka.pics.

Tech stack

  • Backend — Django 4.2 + Django Ninja API, Python 3.11+, managed with uv
  • Frontend — Next.js 16, React 19, Tailwind CSS v4
  • E2E — Playwright with Gherkin/BDD
  • Storage — MinIO (S3-compatible) for media
  • No Celery, no Redis — background work runs synchronously

Repository layout

backend/   Django project + Django Ninja API
frontend/  Next.js app
e2e/       Playwright BDD tests
justfile   task runner

Getting started

Requires Python 3.11+, uv, Node.js, just, and Docker (for the E2E suite).

# backend dependencies
cd backend && uv sync && cd ..

# frontend dependencies
cd frontend && npm install && cd ..

# database
just migrate
just seed        # optional: sample data

# run backend + frontend together
just dev

The frontend dev server runs on port 3005; the backend on Django's default port 8000.

Common tasks

Run just to list every recipe.

Command Description
just dev Start backend + frontend
just backend / just frontend Start one side only
just migrate Run database migrations
just seed Seed the database with sample data
just shell Open the Django shell
just test Backend unit tests
just test-cov Backend tests with coverage
just e2e End-to-end tests (via Docker)
just lint / just lint-fix Lint the backend (ruff)
just lint-frontend Lint the frontend

Testing

  • Unitjust test runs pytest, scoped to resmin/api/.
  • End-to-endjust e2e runs the Playwright BDD suite via Docker.

Deploying to a new server

MinIO bucket policy (important)

When you stand up MinIO with a new bucket, its default public policy includes s3:ListBucket, which lets any anonymous visitor enumerate every object via GET /<bucket>/. That exposes the storage paths of every avatar and photo response on the site (including ones meant to live behind a private group). The app only needs s3:GetObject so individual files load via <img src>; listing is never required.

Lock the bucket down to download-only access after creating it:

mc alias set local https://<minio-host> <access-key> <secret-key> --api S3v4
mc anonymous set download local/<bucket-name>

Verify:

curl -I https://<minio-host>/<bucket-name>/             # expect 403
curl -I https://<minio-host>/<bucket-name>/<known-key>  # expect 200

License

MIT — see LICENSE.

About

A question/answer website that you answer questions with visual stories.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors