rfds: url shortener
diff --git a/docs/rfd/4_URL_SHORTENER.md b/docs/rfd/4_URL_SHORTENER.md
new file mode 100644
index 0000000..9376976
--- /dev/null
+++ b/docs/rfd/4_URL_SHORTENER.md
@@ -0,0 +1,56 @@
+# URL Shortener
+URL shortener will be one of the first party applications developed and published by pcloud team.
+
+## Background
+PCloud 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**
+
+## Goals
+* Authenticated user must be able to assign name to any given URL address.
+* User can choose name manually or generate it randomly.
+* User must be able to view list of all named URLs owned by them.
+* [Stretch] User must be able to transfer ownership of the name to the other user.
+* [Stretch] Administrator of the system must be able to act as any other user.
+
+## Non-goals
+* 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.
+* [Maybe] Changing address of alread created entry must not be possible.
+
+## Technichal overview
+URL 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.
+
+Form 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.
+
+Storage component will have following interface:
+
+```go
+type NamedAddress struct {
+ // Name of the address. Must be unique across the service.
+ Name string
+ Address string
+ OwnerId string
+ Active bool
+}
+
+type Store interface {
+ // Creates new named address.
+ Create(name, address, ownerId string) error
+ // Activates given named address. Does nothing if named address is already active.
+ Activate(name string) error
+ // Deactivates given named address. Does nothing if named address is already inactive.
+ Deactivate(name string) error
+ // Transfers ownership of the given named address to new owner.
+ ChangeOwner(name, ownerId string) error
+ // Retreives all named addresses owned by given owner.
+ List(ownerId string) ([]NamedAddress, error)
+}
+```
+
+We 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.
+
+Standard [net/http](https://pkg.go.dev/net/http) is sufficient to implement the web server. Server will have just two handlers registered:
+* `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.
+* `POST /` - to create new named address entry
+
+Single 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.
+
+Implementation will go to `apps/url-shortener` directory.