blob: 93769764055d536d2bb53e9abf50b63ce6b2214c [file] [log] [blame] [view]
Giorgi Lekveishvilid4b76ee2023-12-19 18:39:06 +04001# URL Shortener
2URL shortener will be one of the first party applications developed and published by pcloud team.
3
4## Background
5PCloud customers, especially businesses, will want to share documents with easy to find and intuitive names. For example internal design document hosted at https://docs.google.com/document/d/X0N4-M0oI2P9l8NMRN6JZR9ETo1fpPIMUf_LUPB5Omgw/edit can be named and shared as **https://go/auth-service-dd**
6
7## Goals
8* Authenticated user must be able to assign name to any given URL address.
9* User can choose name manually or generate it randomly.
10* User must be able to view list of all named URLs owned by them.
11* [Stretch] User must be able to transfer ownership of the name to the other user.
12* [Stretch] Administrator of the system must be able to act as any other user.
13
14## Non-goals
15* Authentication will be implemented outside of this service. URL shortener can assume that if user can access the page that user has already been authorized.
16* [Maybe] Changing address of alread created entry must not be possible.
17
18## Technichal overview
19URL Shortener service will serve only one page at the root path `/`. At the top of the page must be a form to create new named address entry. And below the form must be listed all the named addresses created by currently logged in user.
20
21Form will have two input texts: one to input the address user wants to name and second one for the name itself. Name can be either entered manually or auto-generated by server (user will have to click **Randomize** button. Clicking **Create** button must store new named entry in the storage.
22
23Storage component will have following interface:
24
25```go
26type NamedAddress struct {
27 // Name of the address. Must be unique across the service.
28 Name string
29 Address string
30 OwnerId string
31 Active bool
32}
33
34type Store interface {
35 // Creates new named address.
36 Create(name, address, ownerId string) error
37 // Activates given named address. Does nothing if named address is already active.
38 Activate(name string) error
39 // Deactivates given named address. Does nothing if named address is already inactive.
40 Deactivate(name string) error
41 // Transfers ownership of the given named address to new owner.
42 ChangeOwner(name, ownerId string) error
43 // Retreives all named addresses owned by given owner.
44 List(ownerId string) ([]NamedAddress, error)
45}
46```
47
48We will have single implementation of the `Store` interface backed by [go-sqlite3](https://github.com/mattn/go-sqlite3). Path to the sqlite3 file will be passed as a flag, which can be parsed and accessed using standard [flag](https://pkg.go.dev/flag) package, for example `./url-shortener --db-path=/path/to/sqlite3.db`. At the startup server must check if file at given path exists and if not create and initialize (create table for named address entries) it with new sqlite db.
49
50Standard [net/http](https://pkg.go.dev/net/http) is sufficient to implement the web server. Server will have just two handlers registered:
51* `GET /` - if request path is `/` render form and list of addresses owner by current user, otherwise (for example `/foo`) server will find named address for `foo` and send HTTP redirect (StatusSeeOther) to address given name was assigned to.
52* `POST /` - to create new named address entry
53
54Single HTML template will be sufficient to render the home page via [html/template](https://pkg.go.dev/html/template) package. And [embed](https://pkg.go.dev/embed) package will be used to embed said HTML template into the final binary.
55
56Implementation will go to `apps/url-shortener` directory.