Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Frontend][API][Update] Lexicon V2.0.0 #53

Merged
merged 25 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ce9dbc8
sync latest version 2 changes (alpha)
starjustice Apr 26, 2023
80c638f
Bug fix: Fix an error with the Topic and Post image URL when using a …
starjustice May 5, 2023
2fc71f4
Bug fix: Post preview with a short URL uploads an image as the source.
starjustice May 11, 2023
057c23c
add tool version, fixing nodejs to version 16
SimonBiggs Jul 3, 2023
6a1895a
fix quickstart command
SimonBiggs Jul 3, 2023
233bdfa
fix react version due to expo request
SimonBiggs Jul 3, 2023
6c206e2
Merge pull request #40 from Human-Compatible/tool-versions
starjustice Jul 5, 2023
1a16bc2
Merge pull request #41 from Human-Compatible/fix-quickstart
starjustice Jul 5, 2023
6dd6af7
Merge pull request #42 from Human-Compatible/update-react-version
starjustice Jul 5, 2023
d06298b
Sync latest version 2 (alpha)
gabriellaputri Jul 6, 2023
63a1569
Sync latest version 2 (alpha)
gabriellaputri Jul 14, 2023
dd1ccf7
Sync latest version 2 (alpha)
gabriellaputri Jul 21, 2023
dc1b846
Sync latest version 2 (alpha)
gabriellaputri Jul 27, 2023
de66ea3
Sync latest version 2 (alpha)
gabriellaputri Aug 3, 2023
d8989a4
Sync latest version 2 (alpha)
gabriellaputri Aug 11, 2023
a80c05c
Sync latest version 2 (alpha)
gabriellaputri Aug 16, 2023
3ae5b44
Sync latest version 2 (alpha)
starjustice Aug 18, 2023
e834d16
Ensure that Github Actions runs on alpha-v2 as well (#46)
Kinostrome Aug 18, 2023
d76a552
Improve Chinese Language Support & Fix Issue with Asset File Names (#47)
Bardreamaster Aug 18, 2023
7f92e42
Sync latest version 2 (alpha)
gabriellaputri Aug 25, 2023
4a6e0dd
Sync latest version 2 (alpha)
gabriellaputri Sep 1, 2023
a98d457
Sync latest version 2 (alpha)
starjustice Sep 11, 2023
828ae9e
Sync latest version 2 (beta)
gabriellaputri Sep 15, 2023
d1344da
Sync latest version 2
starjustice Sep 25, 2023
5bd95f4
resolve conflict pull master
starjustice Sep 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 18 additions & 0 deletions .easignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
node_modules/**/*
npm-debug.*

.expo/*
*/coverage
*/.env
*/playstore_secret.json

frontend/web-build/
frontend/dist

api/lib

# macOS
.DS_Store

# Ignoring other directories
/documentation
8 changes: 0 additions & 8 deletions .expo/settings.json

This file was deleted.

9 changes: 9 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

---
name: Troubleshooting or Bug Report
about: Create a report to help us improve
Expand Down
10 changes: 5 additions & 5 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Type of PR

- [ ] Bug fix (_non-breaking change which fixes an issue_)
- [ ] New feature (_adding a feature following a feature-request issue_)
- [ ] Improvement (_improving an existing feature - includes `style:` and `perf:`commits_)
- [ ] Refactor (_rewriting existing code without any feature change_)
- [ ] (!) This change is or requires a documentation update
- [ ] 🐞 Bug fix (_non-breaking change which fixes an issue_)
- [ ] 🧙‍♂️ New feature (_adding a feature following a feature-request issue_)
- [ ] 🔨 Improvement (_improving an existing feature - includes `style:` and `perf:`commits_)
- [ ] 🏗️ Refactor (_rewriting existing code without any feature change_)
- [ ] ✍️ (!) This change is or requires a documentation update

# Description

Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ name: CI

on:
push:
branches: [master, alpha-v2]
branches: [master, v2.0.0-beta]
pull_request:
branches: [master, alpha-v2]
branches: [master, v2.0.0-beta]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: actions/setup-node@v1
- uses: actions/setup-node@v3
with:
node-version: '16.x'

- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT

- uses: actions/cache@v1
- uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
Expand Down
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 16.20.0
63 changes: 63 additions & 0 deletions PROJECT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Internal Project Documentation

## Usage of `git`

As of Monday, July 3, 2023, usage of `rebase` and force pushing are no longer permitted on this project.

`git merge` is the acceptable approach for resolving conflicts.

### Example Scenario

Typically what you'll do is `merge` the current branch with another branch (often `master`).

For example, let's suppose you've been working on a feature branch named `feature/push-notifications`.

Since you started making changes, `master` has received quite a few commits (from other PRs being merged in).

In fact, you even need to incorporate some of those changes into your branch.

_This approach is step-by-step and very explicit. There are shortcuts to accomplish this. In this case, we list out every step just to be clear._

#### Step 1: Checkout `master` and pull down the latest changes

You need to ensure your local copy of `master` is up-to-date with what's on the remote.

```
git checkout master && git pull
```

#### Step 2: Switch back to your branch

Now that `master` is up-to-date, switch back to `feature/push-notifications`.

```
git checkout feature/push-notifications
```

#### Step 3: Merge with `master` to synchronize your branch with it

```
git merge master
```

#### Step 4: Resolve any merge conflicts and commit the changes

If there are no [conflicts](https://www.atlassian.com/git/tutorials/using-branches/merge-conflicts), the `merge` command will automatically reconcile the differences between the two branches with a specific merge strategy it selects.

If there are changes that need to be resolved, it depends on your development environment. If you're using VS Code, it will automatically parse the files with [conflict markers](https://wincent.com/wiki/Understanding_Git_conflict_markers) and give you a basic UI on top of them to help decide which changes to keep.

Note that sometimes, you may need to accept both changes and make further revisions manually to ensure that the final merged code is correct and hasn't broken anything / erased any changes.

When making a manual merge, you will need to commit the changes you have made to perform the merge. Make sure this is done before attempting to push.

#### Step 5: Push the updated branch

Check `git log` (or a similar interface in your IDE) to view the most recent commit, and ensure it contains all of the latest merged changes.

Once you have verified this, you can push your updated branch to the remote. It should now be synchronized with `master`.

```
git push
```

_Note, if you have not configured a default remote, this command may be something like `git push origin feature/push-notifications`._
62 changes: 30 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,48 +50,66 @@ This will simultaneously launch two processes:
- The Prose GraphQL API Server
- The local Expo dev server, which will enable you to launch the React Native app from your device

The `quickstart` commands are designed to point at an existing Discourse server, [Discourse Meta](https://meta.discourse.org).
The `quickstart` commands are designed to point at an existing **public** Discourse server, [Discourse Meta](https://meta.discourse.org).

Configuring it to point at your own Discourse site will take additional configuration.

You can learn more about this in the [Lexicon Documentation](https://docs.lexicon.is/quick-start).
We guide you through the basics of this in the next section below.

You can also learn more about this process in detail in the [Lexicon Documentation](https://docs.lexicon.is/quick-start).

## Example: Specifying a custom Discourse Site URL

This is a brief example to demonstrate how to quickly point the project at a custom Discourse site.

In the example below, we'll use the [Rust Users forum](https://users.rust-lang.org).

If you'd like, simply change that URL to the URL for your Discourse site in order to follow along with your own site.
You can also follow along using your own site if you'd like.

After running `yarn && yarn generate` from the project root, execute the following:

```
$ echo "PROSE_DISCOURSE_HOST=https://users.rust-lang.org" > api/.env
$ echo "MOBILE_PROSE_URL=http://localhost" > frontend/.env
```

The above statements setup the required environment variables for the Prose GraphQL API and the frontend.
The above command sets the required environment variable for the Prose GraphQL API.

Next, open up `frontend/Config.ts`, and set the value at `config.localDevelopment.proseUrl` to `http://localhost`.

```ts
const config = {
localDevelopment: {
proseUrl: 'http://localhost',
},
// ...
};
```

This instructs the frontend to attempt to connect to a Prose GraphQL API running at `http://localhost`.

- The API (via `PROSE_DISCOURSE_HOST`) has been instructed to attempt to connect to a Discourse instance at `https://users.rust-lang.org`.
To bring it all together:

- The frontend (via `MOBILE_HOST_PROSE`) has been instructed to attempt to connect to a Prose GraphQL API running at `http://localhost` (port 80).
- The frontend (via `localDevelopment.proseUrl`) has been instructed to connect to a Prose GraphQL API running at `http://localhost` (port 80).

- The Prose GraphQL API (via `PROSE_DISCOURSE_HOST`) has been instructed to connect to a Discourse instance at `https://users.rust-lang.org`.

- When you launch the Mobile App via [Expo Go](https://expo.dev/client), it will reach out to the API running at `http://localhost`, which will contact the Discourse server at `https://users.rust-lang.org`, and the content of that server will appear in the Mobile App.

### Important Notes

The API default config instructs the server to listen on a hostname of `0.0.0.0` (the public interface) and port 80.
The API's default config instructs the server to listen on a hostname of `0.0.0.0` (the public interface) and port 80.

<details><summary>The frontend takes some additional steps so that you can use the app on your mobile device... <b>(Read More)</b></summary>
<details><summary>The frontend takes some additional steps so that you can test the app with Expo Go on your mobile device... <b>(Read More)</b></summary>

This may seem confusing at first, but it actually saves you a bit of time.

In this scenario, the frontend app is running on your mobile device via Expo Go, and the Prose GraphQL API is running on your development machine (e.g. laptop).
In this scenario, the frontend app is running on your mobile device via Expo Go, and the Prose GraphQL API is running on your development machine (e.g., your laptop).

So, how could we expect the mobile app to be able to locate a server running on a different device, when we have only told the frontend app to attempt to connect to the API on `localhost`? The API isn't running on your mobile device.

The traditional way to deal with this is to force you to manually lookup your local IP address on the network that your mobile device is also connected to. It would be a value like `192.168.0.53`.

Then, you'd have to update `frontend/.env` with that value.
Then, you'd have to update `frontend/Config.ts` with that value.

Even worse, if your local IP address ever changes, everything would break, and you'd have to update the environment variable again.

Expand Down Expand Up @@ -126,7 +144,7 @@ forwarding Discourse requests to https://users.rust-lang.org
💡 🧘 Yoga - Running GraphQL Server at http://0.0.0.0:8999/graphql
```

### Start Expo to run the frontend app
### Start Expo Go to run the frontend app

After that, **in a separate shell**, start Expo to run the frontend app:

Expand Down Expand Up @@ -173,23 +191,3 @@ If you'd like to contribute to it, or just want to browse it locally, you can ru
yarn docs:install
yarn docs:start
```

### Note: Node 16 required

Our tooling, Docusaurus v2, requires Node version 16 in order to work with it.

You can check your current Node version by running the following command:

```
$ node --version
v14.17.0
```

In order to make this process simpler, we recommend installing [nvm](https://github.com/nvm-sh/nvm) (Node version manager) onto your development machine.

Then you'll be able to quickly switch between versions without issue:

```
$ nvm use 14
Now using node v14.17.0 (npm v8.15.1)
```
1 change: 1 addition & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules/**/*
coverage/
src/generated/
.env
logs/
4 changes: 3 additions & 1 deletion api/deploy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM keymetrics/pm2:12-alpine
FROM keymetrics/pm2:16-alpine

WORKDIR /app

Expand All @@ -13,6 +13,8 @@ RUN yarn
COPY tsconfig.json ./
COPY ./src ./src

RUN yarn generate

RUN yarn build

COPY pm2.json .
Expand Down
49 changes: 49 additions & 0 deletions api/docs/logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Basic Logger

Last updated: 2023/08/28

## Motivation

The Prose API needs a proper logging solution so that users of Lexicon who deploy it can monitor the service for issues. Based on our research, we decided to use Winston for our logger. Winston logger offers a versatile and efficient solution for logging. With support for multiple transport options, customizable log formatting, and different log levels, Winston provides developers with the flexibility to tailor their logging to specific needs.

## Setup

Winston is just a single dependency with the package name [winston](https://github.com/winstonjs/winston), so we added it to the project with `yarn add winston` from within the `api/` directory.

## Transports

In logging, a transport is a destination where logs are stored or displayed, such as a file, console, database, etc. In our logging setup, we mainly use the file transport. But during development, we also add the console transport. We chose the file transport because it offers a simple setup that logs directly into a file. We chose this over transports like [Http and Stream](https://github.com/winstonjs/winston/blob/master/docs/transports.md#built-in-to-winston) because server logs can sometimes contains sensitive information, so we don't want expose the logs on the open internet.

We set up the file transport using a library called [winston-daily-rotate-file](https://github.com/winstonjs/winston-daily-rotate-file), which rotates the log file based on time. In addition to configuring the rotation frequency, we can also specify the maximum file size, the maximum number of files to retain, the number of days to keep files, and more.

Referring to the guidance provided by the [OWASP Logging Cheatsheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html), there are some important points to consider when storing logs in a file system:

1. It is preferable to use a separate partition than those used by the operating system, other application files and user generated content.
2. Apply strict permissions concerning which users can access the directories, and the permissions of files within the directories.
3. In web applications, the logs should not be exposed in web-accessible locations, and if done so, should have restricted access and be configured with a plain text MIME type (not HTML).

## Approach

We make logging easier by directly connecting the logger to the `GraphQL Yoga` instance using a plugin called `useLogger`, which helps us keep all log calls in one central place.

```
useLogger({
logFn: (eventName, events) => {
// Event could be `execute-start` / `execute-end` / `subscribe-start` / `subscribe-end`
// `args` will include the arguments passed to execute/subscribe (in case of "start" event)
// and additional result in case of "end" event.
switch (eventName) {
case 'execute-end':
case 'subscribe-end':
// Do logging
break;
}
},
})
```

We categorize our logs into two distinct files, one exclusively for 'error' level logs, and the other for a compilation of logs across all levels.

## Future Improvement

At the moment, our loggers are mainly used to catch any GraphQL errors that are thrown on the server side. But in the future, we're thinking about logging additional types of server errors, like runtime or network issues.
14 changes: 14 additions & 0 deletions api/docs/typescript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Typescript Usage

The Prose GraphQL makes use of Typescript in multiple ways:

- Nexus for schema generation, which generates Typescript types for use in the resolvers
- Manual type definitions
- As of Tuesday, August 15, 2023, we began incrementally adopting usage of [zod](https://github.com/colinhacks/zod) for type definitions and validation
- @ts-reset for additional type safety checks

Generally, this codebase strives to be as type-safe as possible, and we are always improving upon this.

The original implementation was not very careful with types, and as such there are still cases of implicit any, type assertions, and other bad practices.

Our adoption of tools like zod and @ts-reset are intended to help progressively address lingering type saftey issues.
Loading