# Stuff to implement

- [x] be `jj`-aware for single-commit patch proposals
- [ ] be `jj`-aware for stacked changes

## ssh git access

- [x] fetch from repository
  - [ ] Allow unenthicated ssh git fetches?
    - [ ] Refuse the connection if a connection uses a non-`git` user and doesn't present a key matching the username they use. Explain that they should use the `git` user if they don't have an account.
- [x] push to repository
- [ ] Add an error message and close the connection if the user did not set an SSH key.
- [ ] Add flood protection/mitigation

## SSH ui -- nice to have, not a priority

if a user directly logs in with something like `ssh username@SSH_SERVER_ADDRESS`, show a TUI version of the Web UI. Maybe that could even be the main registration funnel?

- [ ] be able to do common operations via ssh TUI. could be cool to be able to be out of the browser to contribute on the forge.

## Web

- [x] create a logo (maybe (probably) a cute child-like smiling frog) meh emoji will do
- [x] global style integrated into the templates via `<link type="text/css" … />`
- [x] maximize screen real-estate: no huge header, attempt to group logical information in the same block, attempt to put blocks side-by-side.
- [ ] Have a 404 page.
- [x] Add todo support (`- [ ]`/`- [x]`) to rendered markdown
- [ ] Implement link shortcuts to Tickets (`#{ticket_id}` -> `/~{user_or_team}/{current_repo}/tickets/{ticket_id}`) and Patch Proposals (`!{patch_proposal_id}` -> `/~{user_or_team}/{current_repo}/patches/{patch_proposal_id}`)
- [ ] Add dynamic `robots.txt` that echoes back the user-agent and tells to limit to 2 req/s
- [ ] Add flood protection/mitigation

### `/` (index)

- [x] have a landing page that explains what this Frogue instance is about.
  - [x] Have a link to login
  - [x] If registrations are open, have link to register
- [ ] if we are logged in, show the user's Feed? like what a logged in Mastodon/snac/others user would see, but with ForgeFed additions (external activity on the user's repo/tickets/patches)?
  - [x] show AP feed
  - [ ] show instance/forgefed feed 

### `/~{user_or_team}`

Profile page for a user.

#### Registration

- [x] implement open registration (`/register`)
- [x] implement invite-only registration
  - [x] environment variable $FROGUE_REGISTRATION_MODE="open" or $FROGUE_REGISTRATION_MODE="invite_only" to configure the server. defaults to open.
  - [ ] when the DB has no users, the first user registration is open.
  - [x] the user can generate an invite link that is valid $FROGUE_INVITES_VALIDITY_SECONDS, defaults to 48 hours. The user then gives it to someone. A user can only generate $FROGUE_INVITES_ALLOWED_PER_DAY links per day, defaults to 5. The invite link is something like `/register/?invite={UUID}` where UUID is checked against DB for validity. 

#### Profile page

- [x] view / list current repos
  - [ ] order current repos by last activity (creation order for now)
- [ ] edit profile
- [ ] Show latest user Notes/Announces
- [x] create new repository
  - [x] fix the out-of-alignement radio buttons on the new repository page

#### Federation

This is an ActivityPub-compatible stream of messages and updates related to the user. Same for a repository.

- [ ] ActivityPub actor keys are RSA-2048; move to 4096 (or Ed25519 where peers support it). Needs is a key rotation mechanism

- [x] ActivityPub Actor `Person`
- [x] ActivityPub `Notes`
- [x] ActivityPub reactions (`Announce`/`Like`/`EmojiReact`, …)
  - [ ] Outgoing EmojiReact on remote notes
- [x] Unified outbound HTTP signing (sign_post/sign_get helpers)
- [x] Remote actor cache populated with name/preferred_username fields
- [x] Remote actor cache refresh policy (24h staleness check)
- [x] Webfinger and remote actor discovery by handle (@user@host)
- [x] Follow remote actors with Accept/Reject handling
- [x] Receive and store remote notes from followed actors
- [x] Logged-in home feed with remote notes
- [ ] Proxy remote avatar images server-side to protect viewer privacy
- [x] Federate reactions on remote notes

### Repository `/~{user_or_team}/{repo_slug}`

- [x] Rename the route names: 
  - [x] `/~{user_or_team}/{slug}` -> `/~{user_or_team}/{repository_slug}`
  - [x] `/~{user_or_team}/{slug}/tree/{tail}` -> `/~{user_or_team}/{repository_slug}/tree/{ref_or_commit}/{file_path}` 
  - [x] `/~{user_or_team}/{slug}/raw/{tail}` -> `/~{user_or_team}/{repository_slug}/raw/{ref_or_commit}/{file_path}`
- [x] if a user is logged in, use their username in the git URL instead of user `git`. Would that not conflict with the plans to have a WebUI?
- [x] (while we don't allow unenthicated ssh git fetches) Show the web read-only access git url instead of the ssh one if the user is unauthenticated.

#### Summary / Landing

- [x] show readme on landing
  - [x] if the user has a favorite language set in their browser, look for a localized readme, such as README.fr.md or README_fr.md.
- [x] show a list of the 3 latest commited branches with their latest commit (hash,author,first line of commit message)
- [x] show a list of the 3 latest tags with their latest commit  (hash,author,first line of commit message)
- [x] http git access (read-only) `/{user_or_team}/{repo_slug}.git` if user is unauthicated, ssh git access (read-write) if the user is authenticated.

#### Federation

A repository has its own ActivityPub Actor type (`Repository`) that people can follow for updates. We use the ForgeFed `Repository` type (not ActivityPub's `Application` type) as per the ForgeFed specification.

- [x] implement FF `Repository`
  - Note: Branch objects, repo Notes/reactions, likes/stars, tag pushes, Factory, Person sshKeys, Grants, and webfinger for repos are deferred to future work
- [x] implement FF `TicketTracker` 
- [x] implement FF `PatchTracker`


#### Refs viewing

- [x] list all available refs in the repository (branches/tags)

#### Commit History

- [x] list all commits which the given ref has as ancestors.
  - [ ] Implement pagination

#### Diff/Single commit

- [x] diff viewer for a single commit.
  - [x] when a commit hash is shown to the user, it now redirects to the diff of the given commit. On the diff page is a link to the tree of this commit.
- [x] diff viewer for a range of commits (`/compare/{base}...{head}`).
- [ ] Add line numbers to modified files's diffs, each with an anchor you can use to link to a specific line of a file in a diff.
- [x] Generalize as structs the maud components used in diffs so we can re-use them in `/{user_or_team}/{repo_slug}/compare/{base}...{head}`
- [ ] Side-by-side diffs?
- [ ] "intelligent" diffs via something like delta?
- [ ] Folding/unfolding of file headers to hide/show their diffs. All-deletion or all-creation, as well as diffs bigger than say 100 lines should be folded by default.
- [x] Show git stats (~modified,+added,-deleted) for commits/diffs (even for commits lists such as history?).
  - [ ] implement ~modified lines

#### File/tree browser at given ref/commit

- [x] tree browser for a given ref: walk a repository's directory tree at any branch, tag, or commit hash, and open the files in it (source colouring, markdown rendered, raw bytes on their own URL).
- [ ] Add line numbers to viewed files, with link anchors to be able to bring attention to a specific line
- [ ] Add HTTP caching for raw files. If the url mentions a commit directly, we can know when the file has been last modified from the date of the commit. If the url mentions a ref, the modification date is only an indirection away.

#### Tickets (≃ issues)

They have a summary (≃title) with markdown, a description with markdown, a list of tags applied to them, which are created by the repository owner(with default: open,closed,bug,improvement) and finally attachements (limit to smaller than 2Mb, no more than 4 per ticket (Should be configurable by an admin, via envvars for instance)).

- [x] list (with some tags applied by default, such as "open"?)
  - [x] filter the list by tags
  - [x] search (sqlite's full text search?)
  - [ ] Implement pagination
- [x] add
- [x] edit
- [x] delete
- [x] attachments (with size and count limits, configurable via envvars)
  - [ ] dumbass forgot to put form entries to upload attachements…
  - [ ] dumbass forgot² to put envvars for config…
- [x] comments
  - [ ] FTS search
  - [x] federation for comments (migrate comments to proper Notes)
- [x] state (same as patche proposals)
- [x] labels (same as patch proposals) 

#### Patches/Merge requests

An other repository tab. A Patch proposal is created when someone (who can be someone other than the owner on a public repository) pushes via SSH to the special `patches` ref. The code is accepted and put on a special ref named `patches/{patch_id}`, which the user is then informed of. A Patch Proposal (PP) is created with a "draft" status, editable by the person pushing the patch (they _MUST_ have an account to be able to push). The link to the draft PP is provided via text to the user sending the push via SSH.

A Patch Proposal (PP) is comprised of:
- [x] a summary (≃title)
- [x] a description
- [x] a source ref/branch (`patches/{patch_id}`)
- [x] a destination branch (defaults to the repository's `default_branch`)
- [x] a status (enum: open,closed,draft,merged) (default: draft)
- [ ] 0+ tags (maybe we could reuse the ones from the tickets? then we would need a separate "state" for tickets)
- [x] comments
  - [ ] FTS search?
  - [x] federation for comments (Same: Notes)
- [x] A merge policy: fast-forward, fast-forward only, merge commit only, rebase-then-fast-forward

- [x] list PPs (with state filtering)
  - [ ] implement pagination in a second step
- [x] show PP detail (with diff to destination branch, of course)
- [x] merge action (owner-only, with conflict detection and compare-and-swap)

#### Repository settings

- [x] Repository visibility
- [x] label creation / deletion
- [ ] [DANGER ZONE]
  - [ ] slug change
  - [ ] deletion

### User settings

I think this should be something we configure via a special repository. Would be fun, no? Yeah but what about ppl that only want to report bugs?

- [x] SSH key WebUI

### Chores

Everything that's linked to frogue's code

- [x] split the views module in submodules
- [x] Leverage the component-style UI that maud enables more
- [ ] Change the default root data dir to something sensible, such as `$XDG_DATA_DIR`. (don't forget to migrate the existing DB you dumbass)

[DANGER ZONE]: https://music.youtube.com/watch?v=yK0P1Bk8Cx4
