* Add state and taskName in elastic page mappings * Add state and taskName in elastic page interface * Create page with PROCESSING state before scrapping * Update createArticleRequest API * Fix tests * Add default state for pages * Update createArticle API * Update save page * Update save file * Update saving item description * Show unable to parse content for failed page * Fix date parsing * Search for not failed pages * Fix tests * Add test for saveUrl * Update get article saving request api * Update get article test * Add test for articleSavingRequest API * Add test for failure * Return new page id if clientRequestId empty * Update clientRequestId in savePage * Update clientRequestId in saveFile * Replace article with slug in articleSavingRequest * Add slug in articleSavingRequest response * Depreciate article * Use slug in web * Remove article and highlight fragments * Query article.slug on Prod * Show unable to parse description for failed page * Fix a bug having duplicate pages when saving the same url multiple times * Add state in response * Rename variables in removeArticle API * Rename state * Add state in response in web * Make state an enum * Open temporary page by link id * Use an empty reader view as the background for loading pages * Progressively load the article page as content is loaded * Add includePending flag in getArticles API * Set includePending = true in web * Add elastic update mappings in migration script * Add elastic mappings in docker image * Move index_settings.json to migrate package * Remove elastic index creation in api * Move elastic migrations to a separate directory * Remove index_settings from api docker image Co-authored-by: Jackson Harper <jacksonh@gmail.com>
Backend
This workspace is dedicated to API server that uses Apollo GraphQL server and Knex query builder to provide the app with data operations.
GraphQL schema
GraphQL schema is located in schema.ts. In order to use new types, queries or mutations you need to declare them there and then run yarn gql-typegen from the application root to create the necessary typings in order to write GQL queries from the app.
Apollo resolvers and data sources
We make use of Apollo resolvers and data sources. Resolvers typically contain business logic and handling of user domain errors, while data sources are ideally simple atomic database operations.
Interacting with the database
All operations on the database must be wrapped in Knex transaction on a resolver layer. This ensures data integrity and safety with no side effects on a failed operations.
Because we make use of Row Level Security in the database, - all operations typically begin with assuming the role for which policies exist via omnivore.set_claims database function.
ElasticSearch
We use ElasticSearch to store page data in a distributed manner. This is a great way to store data that is not easily searchable.
All the page data is stored in a single index pages. This index is then queried by the app to display the data.
You need to make sure you have an elasticsearch instance running locally (or just use docker-compose).
ES url is specified by ES_URL environment variable (username ES_USERNAME and password ES_PASSWORD can be random strings in local environment).
When you're running elastic for the very first time, you need to create indices and ingest existing data. This can be done by running python elastic_migrate.py.
This operation is idempotent, so you can always run python elastic_migrate.py again to re-ingest all the data.
You can run ElasticSearch separately by using docker-compose -f docker-compose.yml up -d elastic.
Image Proxy (optional for local dev)
Backend API server returns article image links using image proxy
(/imageproxy). You will need to set the env with var IMAGE_PROXY_URL to point
to a running instance of image proxy along with env var IMAGE_PROXY_SECRET. The
same secret env var ought to be passed as config to the running image proxy
service. You can also use the docker-compose-dev.yml file to bring up just the
image proxy service alone (w/ env var for secret specified in the compose file)
by running: docker-compose -f docker-compose-dev.yml up -d imageproxy.
When running locally, use the .env.local file to set up the env variables in your environment.
Set up the database
Refer the using locally section from db README.
Copy .env.example file to .env file:
cp .env.example .env
Run the app
yarn dev