Files
noteplace-server/docs/DESIGN.md
T
haopengzhan f1909da1ad
Go CI / build (push) Failing after 2m42s
Initial commit
feat: create basic server to manage google oauth, account, sessions, places, attributes and ratings.
2025-09-19 02:43:04 -07:00

8.0 KiB

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.

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.