Skip to content

feat: Coiny — full numismatic auction platform#4

Merged
HlibPavlyk merged 89 commits into
masterfrom
refactor-dip
May 29, 2026
Merged

feat: Coiny — full numismatic auction platform#4
HlibPavlyk merged 89 commits into
masterfrom
refactor-dip

Conversation

@HlibPavlyk
Copy link
Copy Markdown
Owner

Coiny — Numismatic Auction Platform

End-to-end build of the bachelor-thesis project: a Ukrainian numismatic
(coins, banknotes, medals) auction marketplace. 89 commits across four
sprints, implementing every layer from domain model to push-to-deploy.

Tech stack

  • Backend: .NET 10, ASP.NET Core controllers, EF Core 10 + PostgreSQL 17,
    MediatR v12 + FluentValidation, Hangfire (Postgres storage), SignalR
    (in-memory backplane), Meilisearch v1 for search.
  • Frontend: React 19 + Vite + TypeScript, Tailwind v4 design tokens,
    TanStack Query, Zustand, custom SignalR client.
  • Integrations: Stripe Connect Express (manual-capture escrow),
    Nova Poshta API v2, Resend, Google OIDC, Cloudflare R2.
  • Architecture: Clean Architecture (Domain → Application → Infrastructure
    → Api), feature-slice folders inside each layer, Result-pattern
    Error contract project-wide.
  • Deploy: Coolify on Hetzner CCX23, Docker multi-stage build,
    Caddy auto-TLS via Let's Encrypt.

Sprint 1 — Foundation

User identity (Email + Google OIDC), JWT-in-HttpOnly-cookie auth,
ASP.NET Core Identity tables, OpenAPI + Scalar UI, Result pattern,
GlobalExceptionHandler, ProblemDetails error contract, .slnx solution
layout, Central Package Management, initial EF migration + seed data
(categories, roles).

Sprint 2 — Lots & bidding

Lot aggregate with category attributes (JSONB), image upload pipeline
to Cloudflare R2, 3-step create-lot wizard with markdown description
editor, lot publishing flow, real-time bid placement with optimistic
EF concurrency, anti-snipe rule (5-min soft-close window),
AuctionCloseJob scheduled via Hangfire on EndsAt, SignalR
broadcast of LotChanged events.

Sprint 3 — Payments & shipping

Stripe Connect Express seller onboarding (Account Links + return URL
flow), manual-capture PaymentIntent on the buyer side, Nova Poshta
address lookup + TTN creation + NovaPoshtaPollingJob, CapturePaymentJob
on NP-delivery, CancelPaymentJob on NP-return, 96h non-payment
sweep + 48h won-pay reminder + email-outbox pattern via Resend,
buyer pay flow with Stripe Elements + 3DS handling, shipment timeline UI.

Sprint 4 — Search, admin, polish, deploy prep

Meilisearch index foundation, outbox-driven sync via SearchIndexFlushJob,
unified /search page with facets (condition, country, metal, price)
and four sort modes, moderation surface (reports queue + dismiss /
take-action / ban-user-with-cascade / soft-delete-lot),
admin-only /moderation/demo for thesis defence with five
short-circuit endpoints, 6 showcase tests tagged for the thesis
test chapter, error pages + empty states + skeleton loaders,
sprint-4 task 15 deploy prep: MIGRATE_ON_STARTUP, real /health
probes, Hangfire dashboard role-gating, docker-compose local parity,
GitHub Actions CI.

Quality

  • 205 backend tests passing (xUnit + FluentAssertions + EF in-memory
    • custom fakes for Stripe / NP / Email / Scheduler).
  • 6 of them marked [Trait("Showcase", "true")] — the test-chapter
    highlight subset.
  • Frontend tsc --noEmit clean, pnpm build clean.
  • CI pipeline (dotnet-ci.yaml) runs backend build + tests +
    showcase-only filter + frontend tsc + build on every push.
  • 6 EF migrations applied cleanly; MIGRATE_ON_STARTUP=true ready
    for first deploy.

Out of scope (documented as future work)

  • Multi-instance horizontal scaling (Redis backplane is DESCRIBE-ONLY
    in THESIS-SCOPE.md §1).
  • Stripe live mode + platform KYC.
  • Localization to Ukrainian (everything English; locale negotiation
    described in docs/06-open-questions.md).
  • Centralized observability (OpenTelemetry stack).
  • Semantic search via vector embeddings.

See docs/thesis-inserts/future-work.md for the full list with the
rationale per item.

Deployment

Pending — Sprint-4 task 15 ships the code-side prep, the infra
provisioning runbook lives in plans/sprint-04-search-admin-polish/ deployment-runbook.md. Demo URL will be https://coiny.best/ once
the runbook is executed.

- update album logic
- delete repository and unit of work patterns implementation
- update/delete album models
- update auth/token logic
- delete discussions logic
- update user profile logic
- update album elements logic
HlibPavlyk added 28 commits May 13, 2026 13:30
@gitguardian
Copy link
Copy Markdown

gitguardian Bot commented May 29, 2026

⚠️ GitGuardian has uncovered 2 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
28811892 Triggered Generic Password 3a5cfe8 docker-compose.yml View secret
28811892 Triggered Generic Password 3a5cfe8 docker-compose.yml View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@HlibPavlyk HlibPavlyk merged commit 1a523bf into master May 29, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant