-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #41 from coderbunker/issue40-internal-schema
issue #40: create internal schema
- Loading branch information
Showing
17 changed files
with
387 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ PGPASSWORD= | |
PGDATABASE=timesheet | ||
PGPORT=5432 | ||
PORT=3000 | ||
TESTAPIKEY=secret |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Heroku Deployment | ||
|
||
## Manage Domain | ||
|
||
### CNAME Setup for Heroku app | ||
|
||
1. Get CNAME from heroku: `heroku domains -a coderbunker-timesheet` | ||
|
||
2. add CNAME to google domains | ||
|
||
| NAME | TYPE | TTL | DATA | | ||
|--------|:--------------:|------:|--------------------------------------:| | ||
| data | CNAME | 1h | data.coderbunker.com.herokudns.com. | | ||
|
||
|
||
### SSL Setup | ||
|
||
Enable SSL automatically managed by heroku. | ||
|
||
## troubleshooting | ||
|
||
want to push an amended history with subtree push? sadly, does not support push. | ||
|
||
create a local branch and force push that first: | ||
|
||
``` | ||
git subtree split --prefix server -b backup-branch | ||
git push -f heroku backup-branch:master | ||
``` | ||
|
||
should now be back to normal... | ||
|
||
## deploying to Heroku | ||
|
||
Creating/updating schema on Heroku instance: | ||
|
||
```bash | ||
psql -v "ON_ERROR_STOP=1" -b -1 -e -f sql/PSQL.sql `heroku pg:credentials:url | tail -1` | ||
``` | ||
|
||
Restarting the dyno (to load changes to the database for example) | ||
|
||
```bash | ||
heroku restart -a coderbunker-timesheet | ||
``` | ||
|
||
## data transfer to/from heroku database | ||
|
||
Pushing the local database: | ||
|
||
```bash | ||
heroku pg:push timesheet postgresql-rigid-65921 --app coderbunker-timesheet | ||
``` | ||
|
||
Pulling the Heroku database locally and making a copy before changing the pulled version | ||
(adjust date): | ||
|
||
```bash | ||
heroku pg:pull postgresql-rigid-65921 heroku-timesheet --app coderbunker-timesheet | ||
psql -c 'CREATE DATABASE "heroku-timesheet-20180416" TEMPLATE "heroku-timesheet";' postgres | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,130 @@ | ||
require('dotenv').config() | ||
|
||
const express = require('express') | ||
const mountRoutes = require('./routes') | ||
const Router = require('express-promise-router') | ||
const bodyParser = require('body-parser') | ||
const { postgraphile } = require("postgraphile"); | ||
const cookieParser = require('cookie-parser'); | ||
const { Pool } = require('pg') | ||
|
||
const app = express() | ||
function createQuery(dburl) { | ||
console.log('connecting to DATABASE_URL=%s', dburl); | ||
|
||
app.use(postgraphile( | ||
process.env.DATABASE_URL || "postgres://localhost/heroku-timesheet", | ||
"postgraphql", | ||
{ | ||
const pool = new Pool({ | ||
connectionString: dburl | ||
}); | ||
|
||
return function(text, params) { | ||
pool.query(text, params); | ||
} | ||
} | ||
|
||
function postgraphileDefaultConfig(config) { | ||
config = config || {}; | ||
return Object.assign({ | ||
dynamicJson: true, | ||
disableDefaultMutations: true, | ||
disableDefaultMutations: false, | ||
graphiql: true, | ||
watchPg: true, | ||
enableCors: true | ||
enableCors: true, | ||
extendedErrors: ['hint', 'detail', 'errcode'] | ||
}, config); | ||
} | ||
|
||
function validateApiKey(apikey) { | ||
return function(req, res, next) { | ||
function err(e) { | ||
res.writeHead(400); | ||
res.end(JSON.stringify({error: e})); | ||
} | ||
if(req.originalUrl.match(/internal/)) { | ||
if(!((req.body && req.body.apikey === apikey) || req.cookies.apikey === apikey)) { | ||
return err(`invalid api key for ${req.originalUrl}`); | ||
} | ||
} | ||
next(); | ||
} | ||
)); | ||
} | ||
|
||
// create a new express-promise-router | ||
// this has the same API as the normal express router except | ||
// it allows you to use async functions as route handlers | ||
function createRouter(router, query) { | ||
router.post('/snapshot', async (req, res) => { | ||
function err(e) { | ||
res.writeHead(400); | ||
res.end(JSON.stringify({error: e})); | ||
} | ||
|
||
if(!req.body.id) { | ||
return err("id is not defined in body") | ||
} | ||
if(!req.body.doc) { | ||
return err("doc is not defined in body") | ||
} | ||
const { rows, fields } = await query( | ||
`SELECT api.snapshot_json($1, $2::json)`, | ||
[ | ||
req.body.id, | ||
JSON.stringify(req.body.doc) | ||
]) | ||
var json = JSON.stringify(rows[0].snapshot_json); | ||
res.writeHead(200, {'content-type':'application/json', 'content-length': Buffer.byteLength(json)}); | ||
res.end(json); | ||
}); | ||
|
||
return router; | ||
} | ||
|
||
function registerEndpoint(app, schema, endpoints) { | ||
if(!endpoints) { | ||
endpoints = { | ||
graphqlRoute: `/${schema}/graphql`, | ||
graphiqlRoute: `/${schema}/graphiql` | ||
} | ||
} | ||
|
||
app.use(postgraphile( | ||
process.env.DATABASE_URL || "postgres://localhost/heroku-timesheet", | ||
schema, | ||
postgraphileDefaultConfig(endpoints) | ||
)); | ||
} | ||
|
||
function createServer(app, router, mountPoint, apikey, port) { | ||
app.use(mountPoint, router); | ||
app.use(cookieParser()); | ||
app.use(validateApiKey(apikey)); | ||
|
||
registerEndpoint(app, 'postgraphql', {}); | ||
registerEndpoint(app, 'internal'); | ||
|
||
// parse application/x-www-form-urlencoded | ||
app.use(bodyParser.urlencoded({ | ||
extended: false | ||
})) | ||
|
||
// parse application/x-www-form-urlencoded | ||
app.use(bodyParser.urlencoded({ | ||
extended: false | ||
})) | ||
// parse application/json | ||
app.use(bodyParser.json({ | ||
limit: "5mb" | ||
})) | ||
|
||
// parse application/json | ||
app.use(bodyParser.json({ | ||
limit: "5mb" | ||
})) | ||
app.use(express.static(__dirname + '/public')); | ||
|
||
app.use(express.static(__dirname + '/public')); | ||
var server = app.listen(port, function() { | ||
console.log(JSON.stringify(server.address())) | ||
const host = server.address().address; | ||
const port = server.address().port; | ||
console.log('timesheet app listening at http://%s:%s', host, port); | ||
}); | ||
|
||
mountRoutes(app) | ||
return server; | ||
} | ||
|
||
console.log('port: %s', process.env.PORT) | ||
var server = app.listen(process.env.PORT, () => { | ||
console.log(JSON.stringify(server.address())) | ||
const host = server.address().address; | ||
const port = server.address().port; | ||
console.log('timesheet app listening at http://%s:%s', host, port); | ||
}); | ||
if (require.main === module) { | ||
const query = createQuery(process.env.DATABASE_URL); | ||
const router = createRouter(new Router(), query); | ||
const server = createServer(express(), router, '/gsuite', process.env.APIKEY, process.env.PORT); | ||
} else { | ||
module.exports = { createServer, createRouter, createQuery }; | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
-- internal interface | ||
\ir internal/schema.sql | ||
\ir internal/group.sql |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.