Files
indie/README.md
2026-07-06 23:13:47 +05:45

230 lines
8.9 KiB
Markdown

# Indie — Independent Website Platform
A platform that lets anyone create, own, and publish their own static website without social media gatekeeping. Built with a drag-and-drop builder and LLM prompt-to-site generation. Every site is backed by a git repository.
---
## Quick Start
### Prerequisites
- Java 17+
- Node.js 18+ and npm
- Docker & Docker Compose (for PostgreSQL, MongoDB, MinIO)
- Angular CLI 17 (`npm install -g @angular/cli@17`)
- Gradle wrapper (included)
### Setup
1. **Start infrastructure:**
```bash
docker compose up -d
```
2. **Start the backend:**
```bash
cd backend
./gradlew bootRun
```
The API will be available at `http://localhost:8080`.
Swagger UI at `http://localhost:8080/swagger-ui.html`.
3. **Start the frontend (separate terminal):**
```bash
cd frontend
npm install
ng serve
```
The app will be available at `http://localhost:4200`.
API calls are proxied to `http://localhost:8080`.
### Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `SPRING_DATASOURCE_URL` | PostgreSQL JDBC URL | `jdbc:postgresql://localhost:5432/indie` |
| `SPRING_DATASOURCE_USERNAME` | DB username | `indie` |
| `SPRING_DATASOURCE_PASSWORD` | DB password | `indie_dev` |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_ID` | Google OAuth 2.0 client ID (omit to disable Google login) | — |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_SECRET` | Google OAuth 2.0 client secret | — |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENT_ID` | GitHub OAuth App client ID (omit to disable GitHub login) | — |
| `SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENT_SECRET` | GitHub OAuth App client secret | — |
| `INDIE_JWT_ACCESS_EXPIRATION` | Access token TTL (ms) | `900000` (15 min) |
| `INDIE_JWT_REFRESH_EXPIRATION` | Refresh token TTL (ms) | `604800000` (7 days) |
| `INDIE_GIT_REPOS_PATH` | Git repositories root | `/var/git/sites/` |
| `INDIE_GIT_AUTHOR_NAME` | Default git author name | `Indie Platform` |
| `INDIE_GIT_AUTHOR_EMAIL` | Default git author email | `git@indie.local` |
---
## Project Structure
```
backend/
├── build.gradle # Dependencies and build config
├── settings.gradle # Project name
├── gradlew / gradlew.bat # Gradle wrapper
├── gradle/wrapper/ # Wrapper JAR + properties
└── src/main/
├── java/com/indie/
│ ├── IndieApplication.java # Spring Boot main class
│ ├── config/
│ │ ├── SecurityConfig.java # HTTP security, JWT filter, OAuth2 login, CORS
│ │ ├── JwtConfig.java # RS256 token generation and validation
│ │ └── GitConfig.java # Git repository settings
│ ├── model/
│ │ ├── User.java # User entity with local + OAuth support
│ │ ├── Site.java # Site entity per user
│ │ ├── Page.java # Page within a site
│ │ ├── Component.java # Component on a page (heading, text, image, etc.)
│ │ ├── JsonbConverter.java # JPA converter for JSONB columns
│ │ └── *.java # Enums (AuthProvider, SiteStatus, ComponentType)
│ ├── repository/
│ │ ├── UserRepository.java
│ │ ├── SiteRepository.java
│ │ ├── PageRepository.java
│ │ └── ComponentRepository.java
│ ├── dto/
│ │ ├── RegisterRequest.java
│ │ ├── LoginRequest.java
│ │ ├── RefreshTokenRequest.java
│ │ ├── AuthResponse.java # JWT tokens + user info
│ │ ├── SiteRequest.java
│ │ ├── SiteResponse.java
│ │ ├── PageRequest.java
│ │ └── PageResponse.java
│ ├── service/
│ │ ├── AuthService.java # Register, login, token refresh
│ │ ├── OAuth2UserService.java # Maps Google/GitHub user info to User entity
│ │ └── OAuth2SuccessHandler.java # Redirects with JWT after OAuth login
│ └── controller/
│ ├── AuthController.java # POST /api/auth/register, /login, /refresh, /logout
│ ├── SiteController.java # CRUD /api/sites
│ └── PageController.java # CRUD /api/sites/{siteId}/pages
└── resources/
└── application.yml # All configuration
frontend/
├── proxy.conf.json # Dev proxy to backend
├── angular.json # Angular CLI configuration
├── tailwind.config.js # Tailwind CSS configuration
├── package.json
└── src/
├── index.html
├── styles.css # Global styles + Tailwind imports
└── app/
├── app.component.ts # Root component
├── app.config.ts # App providers
├── app.routes.ts # Lazy-loaded routes
├── core/
│ ├── models/
│ │ ├── auth-response.ts # AuthResponse & UserInfo interfaces
│ │ ├── site.ts # SiteResponse interface
│ │ └── page.ts # PageResponse interface
│ ├── services/
│ │ ├── auth.service.ts # Auth HTTP + token storage
│ │ ├── site.service.ts # Site CRUD HTTP
│ │ └── page.service.ts # Page CRUD HTTP
│ ├── guards/
│ │ └── auth.guard.ts # Route guard (redirects to /login)
│ └── interceptors/
│ └── jwt.interceptor.ts # Attaches Bearer token
├── auth/
│ ├── login/
│ │ └── login.component.ts # Email/password login form
│ └── register/
│ └── register.component.ts # Name/email/password register form
└── dashboard/
├── dashboard.component.ts # Site cards grid + toolbar
├── create-site-dialog/
│ └── create-site-dialog.ts # Create site dialog
└── delete-site-dialog/
└── delete-site-dialog.ts # Confirm delete dialog
```
---
## API Overview
### Authentication (`/api/auth`)
| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/auth/register` | Register with email + password |
| POST | `/api/auth/login` | Login with email + password |
| POST | `/api/auth/refresh` | Refresh access token |
| POST | `/api/auth/logout` | Logout |
### Sites (`/api/sites`)
| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/sites` | List user's sites |
| POST | `/api/sites` | Create a new site |
| GET | `/api/sites/{id}` | Get site details |
| PUT | `/api/sites/{id}` | Update site |
| DELETE | `/api/sites/{id}` | Delete site |
### Pages (`/api/sites/{siteId}/pages`)
| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/sites/{siteId}/pages` | List pages for a site |
| POST | `/api/sites/{siteId}/pages` | Create a new page |
| GET | `/api/sites/{siteId}/pages/{pageId}` | Get page details |
| PUT | `/api/sites/{siteId}/pages/{pageId}` | Update page |
| DELETE | `/api/sites/{siteId}/pages/{pageId}` | Delete page |
---
## Tech Stack
| Layer | Technology |
|-------|-----------|
| Backend | Java 17, Spring Boot 3.2, Gradle |
| Frontend | Angular 17, Angular Material, Tailwind CSS |
| Relational DB | PostgreSQL 16 |
| Document DB | MongoDB 7 |
| Object Storage | MinIO (dev) / Cloudflare R2 (prod) |
| Auth | Spring Security + OAuth2 Client + JWT (RS256) |
| Git | JGit |
| API Docs | Springdoc OpenAPI (Swagger UI) |
---
## Development
```bash
# Backend
cd backend
./gradlew build # Build
./gradlew test # Run tests
./gradlew bootRun # Run locally (requires docker compose up -d first)
# Frontend
cd frontend
npm install # Install dependencies
ng serve # Dev server at localhost:4200
ng build # Production build
```
---
## Build Status
### v0.1 — Auth & Foundation ✅
- [x] User registration (email/password)
- [x] User login (email/password + JWT)
- [x] OAuth2 login (Google, GitHub) with JWT redirect
- [x] Token refresh with 7-day refresh token
- [x] Site CRUD (create, list, get, update, delete)
- [x] Page CRUD within a site
- [x] Frontend: Login, Register, OAuth callback pages
- [x] Frontend: Dashboard with site cards, create/delete dialogs
- [x] Frontend: JWT interceptor, auth guard, lazy routes