chore: initial repository scaffolding
- Add README with features, quick-start (local + Docker) and docs index - Add MIT LICENSE, root .gitignore and .env.example - Add docker-compose.yml (postgres + backend + frontend) - Add root package.json with install:all/dev helpers - Add Gitea CI workflow (backend syntax check, frontend build)
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# --- Database (used by backend + docker-compose) ---
|
||||
DATABASE_URL=postgres://openstack:openstackpw@localhost:5432/openstack
|
||||
POSTGRES_DB=openstack
|
||||
POSTGRES_USER=openstack
|
||||
POSTGRES_PASSWORD=change-me-in-production
|
||||
|
||||
# --- Backend ---
|
||||
PORT=3000
|
||||
JWT_SECRET=change-me-to-a-long-random-string
|
||||
JWT_EXPIRES_IN=7d
|
||||
CORS_ORIGIN=http://localhost:5173
|
||||
# Comma-separated origins allowed in production, e.g.:
|
||||
# CORS_ORIGIN=https://openstack.example.com
|
||||
|
||||
# --- Frontend (Vite; must start with VITE_) ---
|
||||
VITE_API_URL=http://localhost:3000/api
|
||||
VITE_SOCKET_URL=http://localhost:3000
|
||||
@@ -0,0 +1,25 @@
|
||||
name: ci
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: npm ci
|
||||
working-directory: backend
|
||||
- run: node --check src/index.js && node --check src/socket.js
|
||||
working-directory: backend
|
||||
frontend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- run: npm ci
|
||||
working-directory: frontend
|
||||
- run: npm run build
|
||||
working-directory: frontend
|
||||
@@ -0,0 +1,6 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.env
|
||||
*.log
|
||||
.DS_Store
|
||||
coverage/
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 x3
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
@@ -0,0 +1,104 @@
|
||||
# openStack — Collaborative Workspace (Vue 3 + Express + PostgreSQL)
|
||||
|
||||
A Notion-like collaborative workspace: rich pages, nested hierarchy, workspaces with
|
||||
role-based members, real-time collaboration (Socket.IO), comments, search, and
|
||||
light/dark mode. Self-hostable via Node.js or Docker Compose.
|
||||
|
||||
> **Status:** Web app MVP (see [`docs/ROADMAP.md`](docs/ROADMAP.md) for desktop clients
|
||||
> for Windows / macOS / Linux).
|
||||
|
||||
## Features
|
||||
|
||||
- **Auth** — Register / login with JWT (access token), bcrypt password hashing.
|
||||
- **Workspaces** — Create workspaces, invite members by email (`owner` / `admin` /
|
||||
`member` / `viewer`), change roles, remove members.
|
||||
- **Pages** — Nested pages (`parent_id`), icon + cover, ordering, TipTap rich-text
|
||||
content stored as JSON + rendered HTML.
|
||||
- **Real-time collaboration** — Socket.IO rooms per page: live content broadcast,
|
||||
presence (who is viewing), typing indicators.
|
||||
- **Comments** — Threaded comments per page.
|
||||
- **Search** — Full-text search (`ILIKE` on title/content, trigram-ready).
|
||||
- **Light / dark mode** — CSS variables + persisted user preference.
|
||||
- **Self-hostable** — Documented for bare-metal (`docs/HOSTING.md`) and Docker Compose.
|
||||
|
||||
## Monorepo layout
|
||||
|
||||
```text
|
||||
openStack/
|
||||
├── frontend/ # Vue 3 + Vite + Pinia + Vue Router + TipTap
|
||||
├── backend/ # Express + Socket.IO + pg (PostgreSQL)
|
||||
├── docs/ # SETUP, HOSTING, API, ARCHITECTURE, ROADMAP
|
||||
├── docker-compose.yml # postgres + backend + frontend
|
||||
├── .env.example # All required env vars
|
||||
└── .gitea/workflows/ # CI (lint + build + test)
|
||||
```
|
||||
|
||||
## Quick start (development)
|
||||
|
||||
Requirements: Node.js 20+, PostgreSQL 14+.
|
||||
|
||||
```bash
|
||||
# 1. Clone
|
||||
git clone https://git.sysdaemon.xyz/x3/openStack.git
|
||||
cd openStack
|
||||
|
||||
# 2. Configure
|
||||
cp .env.example .env
|
||||
# edit .env -> DATABASE_URL, JWT_SECRET, ports
|
||||
|
||||
# 3. Database
|
||||
createdb openstack
|
||||
psql openstack < backend/src/db/schema.sql
|
||||
|
||||
# 4. Backend
|
||||
cd backend && npm install && npm run dev
|
||||
# -> http://localhost:3000 (API at /api, health at /api/health)
|
||||
|
||||
# 5. Frontend (new terminal)
|
||||
cd frontend && npm install && npm run dev
|
||||
# -> http://localhost:5173
|
||||
```
|
||||
|
||||
Default dev flow creates the first user via **Register** in the UI; that user can then
|
||||
create workspaces and invite others by email (invited email must have an account).
|
||||
|
||||
## Quick start (Docker Compose)
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# set POSTGRES_PASSWORD, JWT_SECRET, etc.
|
||||
docker compose up --build
|
||||
# frontend -> http://localhost:8080
|
||||
# backend -> http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
See [`docs/HOSTING.md`](docs/HOSTING.md) for production (reverse proxy, TLS, backups).
|
||||
|
||||
## Documentation
|
||||
|
||||
| Doc | Content |
|
||||
|-----|---------|
|
||||
| [`docs/SETUP.md`](docs/SETUP.md) | Local dev setup, DB, env vars, troubleshooting |
|
||||
| [`docs/HOSTING.md`](docs/HOSTING.md) | Bare-metal hosting + Docker Compose hosting |
|
||||
| [`docs/API.md`](docs/API.md) | REST + Socket.IO contract with curl examples |
|
||||
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Data model, auth, realtime design |
|
||||
| [`docs/ROADMAP.md`](docs/ROADMAP.md) | Webapp milestones + desktop clients (Win/Mac/Linux binaries via releases) |
|
||||
|
||||
## Scripts (root)
|
||||
|
||||
```bash
|
||||
npm run install:all # install backend + frontend deps
|
||||
npm run dev # runs backend+frontend concurrently (needs concurrently)
|
||||
```
|
||||
|
||||
## Security notes
|
||||
|
||||
- Passwords hashed with bcrypt (12 rounds). Never stored in plain text.
|
||||
- JWT access tokens (default 7d expiry, configurable). Sent as `Authorization: Bearer <token>`.
|
||||
- Rate limiting on `/api/auth/*`. Helmet headers enabled. CORS allow-list via `CORS_ORIGIN`.
|
||||
- Workspace access enforced server-side on every route (membership check + role check).
|
||||
- Socket.IO authenticates via JWT in `auth.token` and re-checks page access on join.
|
||||
|
||||
## License
|
||||
|
||||
MIT — see [LICENSE](LICENSE).
|
||||
@@ -0,0 +1,45 @@
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-openstack}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-openstack}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-openstackpw}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER:-openstack}"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 10
|
||||
|
||||
backend:
|
||||
build: ./backend
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
DATABASE_URL: postgres://${POSTGRES_USER:-openstack}:${POSTGRES_PASSWORD:-openstackpw}@postgres:5432/${POSTGRES_DB:-openstack}
|
||||
PORT: 3000
|
||||
JWT_SECRET: ${JWT_SECRET:-change-me}
|
||||
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
|
||||
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:8080}
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
args:
|
||||
VITE_API_URL: /api
|
||||
VITE_SOCKET_URL: ""
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- backend
|
||||
ports:
|
||||
- "8080:80"
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "openstack",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"description": "Notion-like collaborative workspace (Vue + Express + Postgres)",
|
||||
"scripts": {
|
||||
"install:all": "npm --prefix backend install && npm --prefix frontend install",
|
||||
"dev": "npx concurrently \"npm --prefix backend run dev\" \"npm --prefix frontend run dev\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^9.0.1"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user