9 files changed,
190 insertions(+),
0 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed by:
GitHub
noreply@github.com
Committed at:
2025-09-25 13:54:45 +0300
Parent:
b3a528a
jump to
| M | .tool-versions |
| A | LICENSE |
| A | README.md |
| M | api/Taskfile.yml |
| A | docs/API.md |
| A | docs/Architecture.md |
| A | docs/CONTRIBUTING.md |
| A | docs/README.md |
| A | docs/screenshot.png |
M
.tool-versions
@@ -2,3 +2,5 @@ golang 1.25.0
golangci-lint 2.4.0 bun 1.2.17 direnv 2.4.0 +golines 0.13.0 +gofumpt 0.9.1
A
LICENSE
@@ -0,0 +1,25 @@
+ GLWT(Good Luck With That) Public License + Copyright (c) Everyone, except Author + +Everyone is permitted to copy, distribute, modify, merge, sell, publish, +sublicense or whatever they want with this software but at their OWN RISK. + + Preamble + +The author has absolutely no clue what the code in this project does. +It might just work or not, there is no third option. + + + GOOD LUCK WITH THAT PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION + + 0. You just DO WHATEVER YOU WANT TO as long as you NEVER LEAVE A +TRACE TO TRACK THE AUTHOR of the original product to blame for or hold +responsible. + +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +Good luck and Godspeed.
A
README.md
@@ -0,0 +1,22 @@
+# Onasty + +Full-stack application for temporary note staring with automatic deletion after being read or upon expiration. + +<img src="./docs/screenshot.png" width=50% height=50%> + +## Features +- π **Auth:** OAuth2 + JWT authentication. +- π§ **Account confirmation:** Email verification for new users. +- π **Password protection:** Secure notes with a password. +- π **Custom slugs:** Choose your own note URL. +- π€ **Optional accounts:** Create an account to manage your notes, or use it anonymously. +- π¦ **Rate limiting:** Protects API from abuse. +- β³ **Editable notes:** Change content or expiration time if the note hasnβt been read yet. + +## π Usage +1. Visit the frontend at `<your hosted url>`(there's no hosted app, yet). +2. Create a note β get a unique link. +3. Share the link β once opened, the note is gone. + +## π Documentation +Documentation on project and how to develop it lives [here](/docs)
M
api/Taskfile.yml
@@ -1,6 +1,9 @@
version: "3" tasks: + install: + - bun install + bundle: - bunx redocly bundle openapi.yml -o dist/bundle.yml
A
docs/API.md
@@ -0,0 +1,5 @@
+# API + +All API is documented with OpenAPI spec and stored in [/api](/api). + +You can access them at `http://localhost:8080` (run in swagger-ui container).
A
docs/Architecture.md
@@ -0,0 +1,83 @@
+# Architecture + +## Project structure +```bash +βββ api/ # OpenAPI spec for the backend +βββ cmd/ +β βββ api # Entry point for the backend app +β βββ seed # Entry point for the db seed app, useful during development +βββ deploy/ # All stuff related to deployment of this app +βββ docs/ # You're here, and reading the docs :D +βββ e2e/ # E2E tests for the API (go) +βββ go.mod +βββ go.sum +βββ infra/ # Configurations for infrastructure(grafana, loki, prometheus, caddy) +βββ internal/ # The core application (go) +β βββ config # > app config duh +β βββ dtos # > data transfer objects +β βββ events # > message publishing +β βββ hasher # > general interface to work with hash +β βββ jwtutil # > jwt token helpers +β βββ logger # > log/slog configuration +β βββ metrics # > Prometheus metrics +β βββ models # > domain entities +β βββ oauth # > interface to work with OAuth2 providers +β βββ service # > business logic (auth, notes, users +β βββ store # > persistence layer(postgres, redis) +β βββ transport # > transport layer(http handlers) +βββ mailer/ # mailer service (go) +βββ migrations/ # DB migrations live here (sql) +βββ Taskfile.yml # task file with all tasks for the app development +βββ web/ # The frontend app (elm) + βββ review # > elm-review configuration + βββ static # > all static file(images, fonts, styles, etc) + βββ src + βββ tests +``` + +## Data flow +1. Frontend/Api -> Backend + - The Elm frontend ([web/](/web)) sends requests to the backend API. +2. Transport layer (http handlers) + - User provided data gets mapped into DTO and passed to service layer. + - DTOs are only used between transport and services; the rest of the application uses domain models. +3. Business logic (services) + - Services receive DTOs, map them into domain models, and implement the use case (auth, notes, users). + - Services may interact with: + - Persistence (store β Postgres, Redis) + - Events (events β NATS) + - Utilities (`jwtutil`, `hasher`) +4. Persistence + - Postgres stores durable data (users, notes). + - Redis handles caching/ephemeral state. +5. Background tasks (fire-and-forget) + - Some operations, like sending verification emails, are published as NATS events. +6. Response + - After business logic is complete, domain models are mapped back to DTOs, and returned via transport layer. + - Elm frontend updates the UI accordingly. +7. Observability + - Services log via logger and export Prometheus metrics (`metrics`). + - Grafana, Loki, and Prometheus provide monitoring. + +## Docker +The project uses multiple Dockerfiles with a multi-stage build approach: +- `builder.Dockerfile` β builds Go binaries and caches dependencies. +- `runtime.Dockerfile` β lightweight Alpine base image with system packages preinstalled (used by app images to speed up builds). +- `core.Dockerfile` β packages the main backend API service. +- `mailer.Dockerfile` β packages the mailer service. + +## Services +- Core service (go) + - Exposes RestAPI (see. [API](/docs/API.md)) + - Handles authentication + - Manages notes life cycle +- Mailer + - Listens for events from the core. + - Sends account confirmation and password reset emails. + - Provides its own Prometheus metrics. + - **NOTE:** all events of the service is documented [here](/mailer/) + +## Frontend +- Built with [elm.land](https://elm.land) +- Uses elm-review rules for consistency and quality. +- Compiled into a static bundle (web/dist), served by Caddy.
A
docs/CONTRIBUTING.md
@@ -0,0 +1,46 @@
+# Getting started +First of, you need have [task](https://taskfile.dev), and [mise](https://mise.jdx.dev) installed. + +```bash +git clone git@github.com:olexsmir/onasty.git +cd onasty +mise use # installs required tools for development +task api:install # installs deps to work with openapi +task web:install # installs all node_modules for the frontend gods +task docker:up # starts all docker containers +task frontend:dev # starts dev server for elm app +task run # recompiled and restart core and mailer services +``` + +# Code Structure Guidelines +See [Architecture](./Architecture). + +# Testing +```bash +task test # runs all tests in the project + # > backend e2e and units + # > frontend units +task test:unit # backend unit tests +task test:e2e # backend e2e tests +task frontend:test # frontend unit tests +``` + +# Coding Style & Linting +- For general editor config [editorconfig](https://editorconfig.org/) is used +- Go + - `gofumpt`, `goimports`, `golines` are used for formatting + - `golangci-lint` is used for linting +- Elm + - `elm-format` is used for formatting + - `elm-review` is used for linting + +# Adding Features +1. Make sure thereβs no duplicate functionality. +1. Add new endpoints to `api/openapi.yml` if needed. +1. Add unit tests or e2e tests as appropriate. +1. For new mailer events: add event struct in `internal/events` and corresponding handler in `mailer/`. + +# Branching & Workflow +- Use feature branches for any changes: `feat/<description>` or `fix/<escription>`. +- Follow [Conventional commit](https://www.conventionalcommits.org/en/v1.0.0) messages. +- Open PR against `main` branch.
A
docs/README.md
@@ -0,0 +1,4 @@
+# Docs +- [Project structure](./Architecture.md) +- [Development](./CONTRIBUTING.md) +- [API](./API.md)