Skip to content

Commit 71d7da4

Browse files
committed
docs: update README with comprehensive app overview and feature set
1 parent 1115e7c commit 71d7da4

1 file changed

Lines changed: 368 additions & 13 deletions

File tree

README.md

Lines changed: 368 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,379 @@
1-
# README
1+
# Issued
22

3-
This README would normally document whatever steps are necessary to get the
4-
application up and running.
3+
Issued is a Rails 8 app for a Hack Club-style flow where users can design apparel with code, track effort through Hackatime, RSVP for an event/launch, and submit orders.
54

6-
Things you may want to cover:
5+
The app includes:
76

8-
* Ruby version
7+
- Hack Club OAuth sign-in
8+
- RSVP flow with open/closed state toggles
9+
- User dashboard with design and order pipeline visibility
10+
- Design editor flow with optional Hackatime project linking
11+
- Admin area for user/product/order management plus RSVP CSV import
912

10-
* System dependencies
13+
## Table of Contents
1114

12-
* Configuration
15+
- [What Is Issued](#what-is-issued)
16+
- [Current Feature Set](#current-feature-set)
17+
- [Tech Stack](#tech-stack)
18+
- [Architecture Overview](#architecture-overview)
19+
- [Data Model Snapshot](#data-model-snapshot)
20+
- [Local Setup](#local-setup)
21+
- [Environment Variables](#environment-variables)
22+
- [Authentication (Hack Club OAuth)](#authentication-hack-club-oauth)
23+
- [Developer Workflow](#developer-workflow)
24+
- [Testing, Linting, and Security](#testing-linting-and-security)
25+
- [Admin Operations](#admin-operations)
26+
- [Deployment](#deployment)
27+
- [Project Structure](#project-structure)
28+
- [Known Gaps / Notes](#known-gaps--notes)
1329

14-
* Database creation
30+
## What Is Issued
1531

16-
* Database initialization
32+
YS: Make Designs with code either using hackatime or the integrated svg editor
33+
WS: Get custom clothes made with your designs
1734

18-
* How to run the test suite
35+
From an admin perspective:
1936

20-
* Services (job queues, cache servers, search engines, etc.)
37+
- Manage users and roles.
38+
- Manage products.
39+
- View/manage orders (some order admin actions are currently stubs).
40+
- Import RSVP records via CSV.
2141

22-
* Deployment instructions
42+
## Current Feature Set
2343

24-
* ...
44+
### Public Pages
45+
46+
- Home page (`/`)
47+
- About page (`/about`)
48+
- FAQ page (`/faq`)
49+
- RSVP page (`/rsvp`)
50+
- RSVP count page (`/rsvps`)
51+
- Dynamic RSVP OG image (`/rsvps/og-image.svg`)
52+
53+
### Auth
54+
55+
- OAuth login entry (`/login`)
56+
- OmniAuth callback (`/auth/:provider/callback`)
57+
- Auth failure handler (`/auth/failure`)
58+
- Logout (`/logout`)
59+
60+
### User Area
61+
62+
- Dashboard (`/dashboard`)
63+
- Designs CRUD-ish flow (`/designs`, plus editor routes)
64+
- Orders pages (`/orders`, `/orders/new`, etc.)
65+
66+
### Admin Area
67+
68+
- Admin dashboard (`/admin`)
69+
- Admin users/products/orders resources
70+
- Admin RSVP listing/import/delete
71+
72+
## Tech Stack
73+
74+
- Ruby: `3.4.9`
75+
- Rails: `8.1.2.1`
76+
- Database: SQLite (`storage/*.sqlite3`)
77+
- Assets: Propshaft + Importmap (no Node bundler required for app runtime)
78+
- Frontend behavior: Turbo + Stimulus
79+
- Auth: OmniAuth + custom Hack Club strategy
80+
- Background/cache/cable: Solid Queue, Solid Cache, Solid Cable
81+
- Deployment support: Docker + Kamal
82+
- Quality/security tooling: RuboCop, Brakeman, bundler-audit, importmap audit
83+
84+
## Architecture Overview
85+
86+
At a high level:
87+
88+
- Controllers handle web flows for home/dashboard/designs/orders/rsvp/admin.
89+
- `SessionsController` + custom OmniAuth strategy manage Hack Club OAuth.
90+
- `HackatimeService` wraps Hackatime API calls for trust/project stats.
91+
- Models connect the design-order-user lifecycle.
92+
- Active Storage stores uploaded assets (SVG previews, product/design images).
93+
94+
Key integration services:
95+
96+
- Hack Club OAuth provider (`lib/omniauth/strategies/hackclub.rb`)
97+
- Hackatime API integration (`app/services/hackatime_service.rb`)
98+
99+
## Data Model Snapshot
100+
101+
Main entities:
102+
103+
- `User`
104+
- OAuth identity (`slack_id`, name, tokens)
105+
- Role enum (`user`, `admin`, `superadmin`)
106+
- Trust + verification + YSWS eligibility fields
107+
- `Design`
108+
- Belongs to a user
109+
- Optional Hackatime project metadata
110+
- Active Storage attachments (`svg`, `image`)
111+
- `DesignEditSession`
112+
- Tracks edit intervals and duration
113+
- `Product`
114+
- Catalog item (with optional image)
115+
- `Order`
116+
- Connects `User`, `Design`, and `Product`
117+
- Status pipeline (`pending`, `processing`, `production`, `completed`, `cancelled`)
118+
- `Rsvp`
119+
- Simple association to `User`
120+
121+
See `db/schema.rb` for source-of-truth schema details.
122+
123+
## Local Setup
124+
125+
### Prerequisites
126+
127+
- Ruby `3.4.9` (matches `.ruby-version`)
128+
- Bundler
129+
- SQLite3
130+
131+
Optional but useful:
132+
133+
- Docker (for containerized runs)
134+
- `gh` CLI (if you use optional CI signoff flow)
135+
136+
### 1) Clone and install
137+
138+
```bash
139+
git clone https://github.com/Acidicts/Issued.git
140+
cd Issued
141+
bundle install
142+
```
143+
144+
### 2) Configure environment
145+
146+
```bash
147+
cp .env.example .env
148+
```
149+
150+
Set at least OAuth variables (see [Environment Variables](#environment-variables)).
151+
152+
### 3) Prepare database
153+
154+
```bash
155+
bin/rails db:prepare
156+
```
157+
158+
### 4) Start app
159+
160+
```bash
161+
bin/dev
162+
```
163+
164+
Then open `http://localhost:3000`.
165+
166+
### One-command bootstrap
167+
168+
If you prefer, use:
169+
170+
```bash
171+
bin/setup
172+
```
173+
174+
`bin/setup` installs dependencies, prepares DB, clears logs/tmp, and starts the dev server unless `--skip-server` is passed.
175+
176+
## Environment Variables
177+
178+
Environment is typically loaded via `dotenv-rails` in development/test.
179+
180+
### Required for login
181+
182+
- `HACKCLUB_CLIENT_ID`
183+
- `HACKCLUB_CLIENT_SECRET`
184+
185+
Without these, `/login` redirects back with an OAuth-not-configured alert.
186+
187+
### Strongly recommended
188+
189+
- `HACKCLUB_REDIRECT_URI`
190+
- Explicit callback URL for OAuth provider config.
191+
- `APP_URL`
192+
- Used to build absolute URLs/OG metadata in helpers/admin views.
193+
194+
### Hackatime integration
195+
196+
- `HACKATIME_API_KEY`
197+
- `HACKATIME_START_DATE` (default is 30 days ago)
198+
- `HACKATIME_CACHE_TTL_SECONDS` (default `300`)
199+
- `HACKATIME_BYPASS_CACHE` (presence disables cache)
200+
201+
### OAuth token fallback (optional)
202+
203+
- `HACKCLUB_ACCESS_TOKEN`
204+
- `HACKCLUB_REFRESH_TOKEN`
205+
206+
These are fallback sources if user/session tokens are unavailable.
207+
208+
### RSVP/event state toggles
209+
210+
- `RUNNING`
211+
- `ENDED`
212+
- `RSVP_OPEN`
213+
214+
Used to drive RSVP and home-page CTA behavior.
215+
216+
### Optional helper integrations
217+
218+
- `EXCHANGE_RATE_API_KEY`
219+
- Enables GBP->USD conversion utility used in product-related helpers.
220+
221+
### Runtime/platform vars
222+
223+
- `PORT` (Puma default is `3000`)
224+
- `PIDFILE` (optional)
225+
- `SOLID_QUEUE_IN_PUMA` (enables Solid Queue plugin inside Puma)
226+
- `RAILS_MASTER_KEY` (required for encrypted credentials in environments that need it)
227+
228+
## Authentication (Hack Club OAuth)
229+
230+
OAuth flow details:
231+
232+
1. User visits `/login`.
233+
2. App redirects to `/auth/hackclub`.
234+
3. Callback hits `/auth/hackclub/callback`.
235+
4. Session is established (`session[:user_id]`, token fields).
236+
5. User record is created/updated from OAuth profile.
237+
238+
Implementation files:
239+
240+
- Initializer: `config/initializers/omniauth.rb`
241+
- Strategy: `lib/omniauth/strategies/hackclub.rb`
242+
- Controller: `app/controllers/sessions_controller.rb`
243+
244+
## Developer Workflow
245+
246+
### Common commands
247+
248+
```bash
249+
# Start local server
250+
bin/dev
251+
252+
# Rails console
253+
bin/rails console
254+
255+
# Prepare DB
256+
bin/rails db:prepare
257+
258+
# Reset DB (destructive)
259+
bin/setup --reset --skip-server
260+
```
261+
262+
### Notes
263+
264+
- `bin/dev` currently execs `bin/rails server` directly.
265+
- This app uses Importmap, so there is no JS bundler build step required for standard development.
266+
267+
## Testing, Linting, and Security
268+
269+
### Run everything (CI parity-ish)
270+
271+
```bash
272+
bin/ci
273+
```
274+
275+
`bin/ci` performs setup, style checks, security scans, tests, and seed replant in test.
276+
277+
### Individual commands
278+
279+
```bash
280+
# Tests
281+
bin/rails test
282+
bin/rails test:system
283+
284+
# Style
285+
bin/rubocop
286+
287+
# Security
288+
bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error
289+
bin/bundler-audit
290+
bin/importmap audit
291+
```
292+
293+
### GitHub Actions
294+
295+
Workflow at `.github/workflows/ci.yml` runs:
296+
297+
- Ruby security scans
298+
- JS dependency audit (importmap)
299+
- RuboCop
300+
- Rails tests
301+
- Optional system tests when present
302+
303+
## Admin Operations
304+
305+
Admin access requires `current_user.admin?` (admin or superadmin role).
306+
307+
### RSVP CSV import
308+
309+
- Endpoint/UI: Admin RSVP page
310+
- Expected CSV headers:
311+
- `slack_id` (required)
312+
- `name` (optional)
313+
314+
The importer creates or updates users by `slack_id`, then creates RSVP records if missing.
315+
316+
### Role updates
317+
318+
- Role changes in admin user update are restricted to `superadmin` users.
319+
320+
## Deployment
321+
322+
### Docker
323+
324+
This repository ships a production-ready multi-stage `Dockerfile`.
325+
326+
```bash
327+
docker build -t issued .
328+
docker run --rm -p 3000:3000 --env-file .env issued
329+
```
330+
331+
Container details:
332+
333+
- Entrypoint: `bin/docker-entrypoint` (prepares DB on startup)
334+
- Health endpoint: `/up`
335+
- Default server: Puma with `config/puma.rb`
336+
337+
### Kamal
338+
339+
`config/deploy.yml` is present for Kamal deploys.
340+
341+
Before using it:
342+
343+
1. Replace placeholder hosts/registry values.
344+
2. Configure secrets (especially `RAILS_MASTER_KEY`) in `.kamal/secrets`.
345+
3. Validate persistent volume strategy (`issued_storage:/rails/storage`) for SQLite and Active Storage data.
346+
347+
## Project Structure
348+
349+
```text
350+
app/
351+
controllers/ # user, auth, RSVP, admin flows
352+
models/ # User, Design, Order, Product, Rsvp, DesignEditSession
353+
services/ # Hackatime integration
354+
views/ # ERB templates
355+
config/
356+
routes.rb # route map
357+
initializers/ # OmniAuth and framework setup
358+
db/
359+
schema.rb # current schema state
360+
lib/
361+
omniauth/strategies/hackclub.rb
362+
bin/
363+
setup, dev, ci, rails, rubocop, brakeman, bundler-audit
364+
```
365+
366+
## Known Gaps / Notes
367+
368+
- `Admin::OrdersController` methods are currently stubs and should be completed before relying on full admin order operations.
369+
- `Design` enforces global uniqueness for `hackatime_project`; if project sharing across users is desired, that constraint may need redesign.
370+
- `.env.example` includes some placeholders and may contain redundant entries; keep local `.env` aligned with actual variables used in code.
371+
372+
## Contributing
373+
374+
1. Create a branch.
375+
2. Make changes with tests.
376+
3. Run `bin/ci` locally.
377+
4. Open a PR.
378+
379+
If you are introducing new env vars, migrations, or operational scripts, update this README in the same PR.

0 commit comments

Comments
 (0)