feat: create basic server to manage google oauth, account, sessions, places, attributes and ratings.
This commit is contained in:
+211
@@ -0,0 +1,211 @@
|
||||
# NotePlace: Design Document (Go Backend)
|
||||
|
||||
## 1. Overview
|
||||
|
||||
NotePlace is a web application for rating and commenting on aspects of a place. This document outlines the architecture for a **Go-based backend server**. The primary interaction method for this phase is `curl`, and authentication is handled via a CLI-friendly Google OAuth 2.0 flow.
|
||||
|
||||
## 2. Technology Stack
|
||||
|
||||
* **Backend:** **Go** (using the Gin web framework for routing and middleware).
|
||||
* **Database:** **JSON File**. The server reads from and writes to a `db.json` file on startup and after modifications.
|
||||
* **Authentication:** **Google OAuth 2.0 for Mobile & Desktop Apps**. This flow allows a user to authorize the application in a browser while the CLI waits for confirmation.
|
||||
|
||||
## 3. Authentication Flow (CLI-Based)
|
||||
|
||||
Since the client is a command-line tool (`curl`), a standard browser redirect is not used. The implemented flow is as follows:
|
||||
|
||||
1. **Initiate Login:** The user makes a request to the `/api/auth/google/cli/login` endpoint.
|
||||
2. **Receive Instructions:** The server responds with a `verification_url` (e.g., `https://www.google.com/device`) and a `user_code` for the user to enter at that URL.
|
||||
3. **User Authorizes:** The user opens the URL in their browser, logs into their Google account, and enters the `user_code` to grant permission.
|
||||
4. **Server Polls for Token:** While the user is authorizing, the Go server polls Google's token endpoint.
|
||||
5. **Authentication Complete:** Once the user grants permission, Google provides the server with an access token. The server then creates a session and returns its ID to the user's initial login request.
|
||||
6. **Authenticated Requests:** The user includes this session ID directly in the `Authorization` header for all subsequent `curl` requests to protected endpoints (e.g., `Authorization: <YOUR_SESSION_ID>`).
|
||||
|
||||
## 4. Data Models (Go Structs)
|
||||
|
||||
The data is modeled using Go structs, which are serialized to and from JSON.
|
||||
|
||||
```go
|
||||
package models
|
||||
|
||||
type RoleType int
|
||||
|
||||
const (
|
||||
ADMIN RoleType = iota
|
||||
TRUSTED
|
||||
USER
|
||||
)
|
||||
|
||||
// User represents an authenticated user.
|
||||
type User struct {
|
||||
ID string `json:"id"` // e.g., "user-google-123"
|
||||
GoogleID string `json:"googleId"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Email string `json:"email"`
|
||||
Role RoleType `json:"role"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
ID string `json:"id"`
|
||||
UserID string `json:"userId"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// Place represents a physical location.
|
||||
type Place struct {
|
||||
ID string `json:"id"` // e.g., "place-001"
|
||||
Name string `json:"name"`
|
||||
Category string `json:"category"` // e.g., "Restaurant"
|
||||
Address Address `json:"address"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
// Address is a sub-struct for Place.
|
||||
type Address struct {
|
||||
Street string `json:"street"`
|
||||
City string `json:"city"`
|
||||
State string `json:"state"`
|
||||
Zip string `json:"zip"`
|
||||
Country string `json:"country"`
|
||||
}
|
||||
|
||||
type Category struct {
|
||||
ID string `json:"category"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type ScopeType int
|
||||
|
||||
const (
|
||||
CATEGORY ScopeType = iota
|
||||
PLACE
|
||||
)
|
||||
|
||||
// Attribute defines a "thing" that can be rated, with a specific scope.
|
||||
type Attribute struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Scope ScopeType `json:"scope"`
|
||||
OwnerID string `json:"ownerID,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Attachment string `json:"attachment,omitempty"`
|
||||
}
|
||||
|
||||
// Rating is the central record linking a user, place, and attribute.
|
||||
type Rating struct {
|
||||
ID string `json:"id"`
|
||||
PlaceID string `json:"placeId"`
|
||||
AttributeID string `json:"attributeId"`
|
||||
UserID string `json:"userId"`
|
||||
Score int `json:"score"` // 1-10
|
||||
Comment string `json:"comment,omitempty"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
```
|
||||
|
||||
## 5. API Endpoints with `curl` Examples
|
||||
|
||||
All routes are prefixed with `/api`. Authenticated routes require a token passed in the header: `Authorization: <YOUR_TOKEN>`.
|
||||
|
||||
---
|
||||
|
||||
### **Auth**
|
||||
|
||||
* **`GET /api/auth/google/cli/login`**
|
||||
* Description: Starts the CLI login process.
|
||||
* `curl http://localhost:3001/api/auth/google/cli/login`
|
||||
|
||||
* **`POST /api/auth/logout`**
|
||||
* Description: Logs the user out (invalidates the token).
|
||||
* `curl -X POST -H "Authorization: <YOUR_TOKEN>" http://localhost:3001/api/auth/logout`
|
||||
|
||||
---
|
||||
|
||||
### **Places**
|
||||
|
||||
* **`GET /api/places`**
|
||||
* Description: Get a list of all places.
|
||||
* `curl http://localhost:3001/api/places`
|
||||
|
||||
* **`POST /api/places`**
|
||||
* Description: Create a new place.
|
||||
* `curl -X POST -H "Authorization: <YOUR_TOKEN>" -H "Content-Type: application/json" -d '{"name":"The Grand Restaurant","category":"Restaurant","address":{"street":"123 Main St","city":"Anytown","state":"CA","zip":"12345","country":"USA"}}' http://localhost:3001/api/places`
|
||||
|
||||
* **`GET /api/places/:id`**
|
||||
* Description: Get details for a single place.
|
||||
* `curl http://localhost:3001/api/places/place-001`
|
||||
|
||||
* **`GET /api/places/:id/ratings`**
|
||||
* Description: Get all ratings for a specific place.
|
||||
* `curl http://localhost:3001/api/places/place-001/ratings`
|
||||
|
||||
* **`GET /api/places/:id/attributes`**
|
||||
* Description: Get relevant attributes for a place.
|
||||
* `curl http://localhost:3001/api/places/place-001/attributes`
|
||||
|
||||
---
|
||||
|
||||
### **Ratings**
|
||||
|
||||
* **`POST /api/ratings`**
|
||||
* Description: Create a new rating.
|
||||
* `curl -X POST -H "Authorization: <YOUR_TOKEN>" -H "Content-Type: application/json" -d '{"placeId":"place-001","attributeId":"attr-service","score":9,"comment":"Excellent service!"}' http://localhost:3001/api/ratings`
|
||||
|
||||
* **`PUT /api/ratings/:id`**
|
||||
* Description: Update a rating.
|
||||
* `curl -X PUT -H "Authorization: <YOUR_TOKEN>" -H "Content-Type: application/json" -d '{"score":10,"comment":"Truly the best!"}' http://localhost:3001/api/ratings/rating-12345`
|
||||
|
||||
* **`DELETE /api/ratings/:id`**
|
||||
* Description: Delete a rating.
|
||||
* `curl -X DELETE -H "Authorization: <YOUR_TOKEN>" http://localhost:3001/api/ratings/rating-12345`
|
||||
|
||||
* **`GET /api/ratings/my-ratings`**
|
||||
* Description: Get all ratings for the current user.
|
||||
* `curl -H "Authorization: <YOUR_TOKEN>" http://localhost:3001/api/ratings/my-ratings`
|
||||
|
||||
---
|
||||
|
||||
### **Attributes**
|
||||
|
||||
* **`POST /api/attributes`**
|
||||
* Description: Create a new attribute.
|
||||
* `curl -X POST -H "Authorization: <YOUR_TOKEN>" -H "Content-Type: application/json" -d '{"name":"Cleanliness","scope":"COMMON","placeCategory":"Restaurant"}' http://localhost:3001/api/attributes`
|
||||
|
||||
## 6. Project Structure (Go)
|
||||
|
||||
```
|
||||
/noteplace
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── db.json
|
||||
├── DESIGN.md
|
||||
├── start_server.sh
|
||||
├── stop_server.sh
|
||||
├── cmd/
|
||||
│ └── server.go # Main application entry point
|
||||
├── hack/
|
||||
│ └── createPlace.sh
|
||||
├── internal/
|
||||
│ ├── api/ # HTTP handlers and routing
|
||||
│ ├── auth/ # Google OAuth logic
|
||||
│ ├── models/ # Go struct definitions
|
||||
│ ├── store/ # Data access logic (reading/writing db.json)
|
||||
│ └── test/
|
||||
│ ├── api_attributes_test.go
|
||||
│ ├── api_places_test.go
|
||||
│ ├── api_test.go
|
||||
│ ├── store_test.go
|
||||
│ └── test_utils.go
|
||||
```
|
||||
|
||||
## 7. Future Enhancements
|
||||
|
||||
1. **Enhanced Authentication:** Implement JWT refresh tokens and more robust session management.
|
||||
2. **Database Migration:** Transition from JSON file to a proper database (e.g., PostgreSQL, SQLite) for better scalability and data integrity.
|
||||
3. **User Roles and Permissions:** Implement a more granular role-based access control system.
|
||||
4. **Error Handling:** Improve API error responses for better client-side handling.
|
||||
5. **Testing:** Expand unit and integration test coverage for all API endpoints and business logic.
|
||||
6. **Frontend Integration:** Develop a web or mobile frontend to interact with the API.
|
||||
7. **Deployment Automation:** Set up CI/CD pipelines for automated testing and deployment.
|
||||
Reference in New Issue
Block a user