First commit
This commit is contained in:
27
README.md
Normal file
27
README.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# nwiki backend
|
||||||
|
A multi-user wiki backend that provides a stateless REST API for managing
|
||||||
|
Markdown articles, tags, and user access via OAuth. Handles content storage,
|
||||||
|
tag-based queries, and access control for collaborative editing.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- OAuth 2.0 authentication and authorization
|
||||||
|
- Stateless RESTful API design
|
||||||
|
- Markdown article storage and retrieval
|
||||||
|
- Tag management and filtering
|
||||||
|
- Multi-user access control and content ownership
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
- *Language:* Go
|
||||||
|
- *Framework:* Gin
|
||||||
|
- *Database:* SQL
|
||||||
|
- *Auth:* OAuth 2.0
|
||||||
|
- *Storage:* In-database only (no file system)
|
||||||
|
|
||||||
|
## Build & Run
|
||||||
|
```sh
|
||||||
|
go build -o nwikid ./src
|
||||||
|
./nwikid
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
- [Gin Documentation](https://gin-gonic.com/en/docs/)
|
||||||
68
doc/ARCHITECTURE.MD
Normal file
68
doc/ARCHITECTURE.MD
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# Backend Architecture
|
||||||
|
|
||||||
|
This document outlines the architecture of the backend for nwiki. The backend is
|
||||||
|
a stateless HTTP API that manages articles, posts, tags, and authenticated user
|
||||||
|
access. It uses OAuth 2.0 for authentication and a SQL database for persistent
|
||||||
|
storage. No file system is used.
|
||||||
|
|
||||||
|
## Main Entry Point
|
||||||
|
The backend is initialized from a single entry point that configures the HTTP
|
||||||
|
router, applies middleware, and registers domain-specific route groups.
|
||||||
|
All business logic is organized under domain packages and exposed through a
|
||||||
|
RESTful interface.
|
||||||
|
|
||||||
|
## Middleware
|
||||||
|
Middleware functions are applied globally or scoped to specific route groups.
|
||||||
|
They operate in sequence to process requests before reaching route handlers.
|
||||||
|
|
||||||
|
### Middleware Components
|
||||||
|
|
||||||
|
- **Authentication**
|
||||||
|
Verifies OAuth 2.0 bearer tokens and associates requests with authenticated
|
||||||
|
users. Required for all operations that involve data creation, modification,
|
||||||
|
or deletion.
|
||||||
|
|
||||||
|
- **CORS**
|
||||||
|
Adds cross-origin headers to support browser-based clients.
|
||||||
|
|
||||||
|
- **Logging**
|
||||||
|
Logs request method, route, status code, and execution time for observability.
|
||||||
|
|
||||||
|
- **Error Handling**
|
||||||
|
Normalizes internal errors into structured JSON responses.
|
||||||
|
|
||||||
|
## API Domains
|
||||||
|
The backend groups its endpoints into logical domains, each with distinct
|
||||||
|
responsibilities.
|
||||||
|
|
||||||
|
### Articles
|
||||||
|
Represents content metadata and serves as the logical container for a topic or
|
||||||
|
document. Articles do not store the content body directly. Articles are used
|
||||||
|
for indexing, access control enforcement, and cross-tag navigation.
|
||||||
|
|
||||||
|
### Posts
|
||||||
|
Implements versioning for article content. Each post represents a version of the
|
||||||
|
article body in Markdown and is tied to both an article and the author of the
|
||||||
|
version. Multiple posts may exist per article, forming a history of revisions.
|
||||||
|
|
||||||
|
Posts are immutable after creation and store:
|
||||||
|
|
||||||
|
### Tags
|
||||||
|
Tags are lightweight descriptors used to categorize articles. Tags support
|
||||||
|
filtering and navigation across the platform. They are stored in a normalized
|
||||||
|
table and can be linked to multiple articles entities.
|
||||||
|
|
||||||
|
## Request Lifecycle
|
||||||
|
1. The client sends an HTTP request, optionally including an OAuth token.
|
||||||
|
2. Middleware validates the request and injects user context if authenticated.
|
||||||
|
3. The request is routed to a domain handler based on HTTP method and path.
|
||||||
|
4. Business logic processes the request, interacting with the SQL database.
|
||||||
|
5. A structured JSON response is returned to the client.
|
||||||
|
|
||||||
|
## Design Principles
|
||||||
|
- **Statelessness**: All client context is passed with each request via tokens.
|
||||||
|
- **Modularity**: API logic is organized by content domain and kept isolated.
|
||||||
|
- **Security**: All write operations require valid OAuth authentication.
|
||||||
|
- **Scalability**: Stateless design supports horizontal scaling.
|
||||||
|
- **Portability**: No file system dependencies; suitable for containerized\
|
||||||
|
environments.
|
||||||
46
doc/CONTRIBUTING.md
Normal file
46
doc/CONTRIBUTING.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Contributors Guide
|
||||||
|
|
||||||
|
This document describes the contribution process and formatting standards for
|
||||||
|
this project. All contributors are expected to follow these guidelines to ensure
|
||||||
|
a consistent and maintainable codebase.
|
||||||
|
|
||||||
|
## Contribution Workflow
|
||||||
|
|
||||||
|
- Work must be done in a dedicated branch (e.g., `feature/xyz`, `fix/abc`).
|
||||||
|
- Code must follow the established structure under `src/`.
|
||||||
|
- All contributions must be made through pull requests to the `main` branch.
|
||||||
|
- Contributions must include meaningful commit messages that follow the defined\
|
||||||
|
format.
|
||||||
|
|
||||||
|
## Commit Message Format
|
||||||
|
This project uses [Gitmoji](https://gitmoji.dev/). Each commit message must
|
||||||
|
begin with a Gitmoji and follow the defined structure.
|
||||||
|
|
||||||
|
### Format
|
||||||
|
```
|
||||||
|
:emoji: Subject line
|
||||||
|
|
||||||
|
[Optional body message]
|
||||||
|
```
|
||||||
|
|
||||||
|
- The subject line must be written in the **imperative mood**, **capitalized**,\
|
||||||
|
and **limited to 80 characters maximum**.
|
||||||
|
- The optional body should be wrapped at **80 characters per line**.
|
||||||
|
- The subject must not end with a period.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```
|
||||||
|
:memo: Update README with usage examples
|
||||||
|
```
|
||||||
|
## Contribution Steps
|
||||||
|
|
||||||
|
1. Fork the repository.
|
||||||
|
2. Create a new branch: `git checkout -b feature/my-feature`.
|
||||||
|
3. Write code and commit using the specified format.
|
||||||
|
4. Push to the forked repository: `git push origin feature/my-feature`.
|
||||||
|
5. Open a pull request with a clear, descriptive title.
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
By contributing to this project, all contributors agree that their code will be
|
||||||
|
licensed under the same license as the project.
|
||||||
44
doc/DATABASE.md
Normal file
44
doc/DATABASE.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Database Design
|
||||||
|
```mermaid
|
||||||
|
erDiagram
|
||||||
|
Authors }o--|| Articles : Author
|
||||||
|
Tagging }o--|| Tags : Tag
|
||||||
|
Tagging }o--|| Articles : Article
|
||||||
|
Articles ||--|| Posts : Last_Post
|
||||||
|
Articles ||--o{ Posts : Main_Article
|
||||||
|
|
||||||
|
Articles {
|
||||||
|
INTEGER rowid PK "Article, Main_Article"
|
||||||
|
TEXT(128) title
|
||||||
|
TEXT(512) description
|
||||||
|
TIMESTAMP timestamp
|
||||||
|
BOOLEAN public
|
||||||
|
INTEGER author_id FK "Author"
|
||||||
|
INTEGER lastpost_id FK "Last_Post"
|
||||||
|
}
|
||||||
|
|
||||||
|
Authors {
|
||||||
|
INTEGER rowid PK "Author"
|
||||||
|
TEXT(32) sub
|
||||||
|
TEXT(32) iss
|
||||||
|
TEXT(64) username
|
||||||
|
}
|
||||||
|
|
||||||
|
Tags {
|
||||||
|
INTEGER rowid PK "Tag"
|
||||||
|
TEXT(32) title
|
||||||
|
}
|
||||||
|
|
||||||
|
Tagging {
|
||||||
|
INTEGER rowid PK
|
||||||
|
INTEGER tag_id FK "Tag"
|
||||||
|
INTEGER article_id FK "Article"
|
||||||
|
}
|
||||||
|
|
||||||
|
Posts {
|
||||||
|
INTEGER rowid PK "Last_Post"
|
||||||
|
INTEGER article_id FK "Main_Article"
|
||||||
|
TIMESTAMP timestamp
|
||||||
|
TEXT(5000) body
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user