- Pick a database library that no one is working on.
- State your goals for the first cut of the domain API.
- Pick a limited set of higher-order design goals that you would like to in the first cut of the domain API.
- Quickly get a working implementation of at least the following APIs: tenant, user, role, permission.
- Refer to the Domain module in the skeleton folder to get a working idea. The type signatures will need to be modified depending on your DB library and design goals.
- Refer to the JSON API spec to understand how the domain API will finally be used in the web-app
- Refer to the motivation behind the spec to get more context.
- Raise a PR to get feedback on the direction.
- If all is good, implement the other parts of the API: product, variants, photos
- Pick one higher-order design goals problem, refactor your code, raise a PR, and repeat...
- Somewhere in this process, you'll be happy with the domain API and can start building the web API on top of it.
The central idea is to NOT deviate from the goals stated at the beginning of a development sprint (unless you hit a brick-wall during implementation!) You'll come across a lot of interesting problems that should be answered, hold on to them. Put them in a backlog. We'll tackle them in a later sprint.
- Open a PR against your branch before you start working on the sprint. Tag it with the
sprint
label - Use the PR description to formally state what you would like to achieve at the end of the sprint. Being detailed helps. Writing down your thoughts will help you structure them.
- Put a timeline to the sprint -- try to keep sprints short enough so that they fit within a week.
- Keep committing to your branch - the PR will keep getting updated automatically.
- Comment on the PR when you feel it's ready to be merged (or you'd like someone to quickly review it).
- Get it merged.
- Close the PR with a comment that answers the following:
- What got done in this sprint
- What got pushed to the next sprint
- Any interesting learnings/roadblocks/issues/thoughts/comments
- Lobby @ Gitter IM for general discussions. It's a public room, so even if you're not an active contributor you are welcome to join the discussion.
- Standup @ Gitter IM for daily standups. It's a private room only for active contributors. Every day, we would expect you to answer the following questions at the beginning of your work day (in your timezone):
- Did you work on what you wanted to yesterday? If not, what happened?
- What will you work on today?
- What obstacles or issues are impeding your progress?
DB library | Who's working on it |
---|---|
Persistent | wz1000 |
Opaleye | sras |
HDBC | jfoutz |
Haskell Relational Record | mgmeier |
HASQL | no one, yet |
A lot of people are excited about building a JSON API in Servant and everyone seems to be picking that. We're actively looking for contributors who can pick other web libraries.
Web library | Who's working on it |
---|---|
Servant | wz1000, jfoutz |
Yesod | no one, yet |
Snap | no one, yet |
Happstack | no one, yet |
Library/framework | Who's working on it |
---|---|
Elm | No one yet |
Purescript | No one yet |
Reflex FRP | meditans |
- Make nonsensical states non-representible in the domain model. eg. product can have only two types -- physical and digital. Status can have only few values. Basically a lot of ADT usage.
- Lift more invariants to the type-level.
- Investigate how testing is (or could be) done in the various domains, re-interpreting the type of test commonly used in web development (Unit, Controller, Integration tests) if necessary, to write them in idiomatic ways.
- Create documentation for successful workflows/techniques.
- Best way to deal with housekeeping columns, like
createdAt
,updatedAt
- Implementing audit logs
- Ensuring type-safety in the create/edit/update calls for each DB model, such that an accidental write of a "protected" field is not possible. Example of such fields:
createdAt
,updatedAt
,id
,status
,type
, etc. (fields that need some side-effects or workflow to change) - How to deal with DB updates?
- Should the domain API take the complete record as an argument? Who should be responsible for loading the record from the DB? How many times will we be loading the same record from the DB, if we need to chain/compose different update APIs together?
- Should the domain API take a diff as an argument? How do we represent a diff in a typesafe manner?
- Implementing validations
- Changing response JSON based on incoming request
- DB transactions
- Implementing authorization
- JSONB, ENUM, and Array support in DB library
- Redis caching at object level
- Redis caching at page level
- Architectural concerns
- Create a reusable collection of abstractions for most used ui components (forms etc.)
- Develop a coherent story on how to share data structures with backend.
- Investigate the tradeoff of doing all the implementation in haskell vs. interface, via haskell, to html templates.
- Investigate how to integrate with existing jQuery widgets (calendar, accordion, search/sort tables, editable grids, etc)
- Forms relying only on server side validation or with mixed client/server side validation
- Investigate the preferred way to architecture an application. How powerful, and how general, is it?
- Find a simple and elegant way to do client-side routing. Bonus points if it's easily integrable with the server.
- Analyze, in the case of a language barrier to cross, the tradeoffs involved. In particular if is it possible to automatically reutilize the same structures (like the description of an API) on both frontend and backend.
- Deployment concerns
- Minification toolchain to reduce the final JS size (closure compiler, specific ghcjs compilation options etc.)
- Progressive loading of JS files to reduce initial page-load time
- Server-side rendering of initial page-load
- Benchmarking how well the generated app fares on mobile
Please raise a PR against this file to add more higher-order design goals
Been writing code since I was 12 years old. Wrote the same paint program in GwBasic, QBasic, Pascal, C, and C++ (remember BGI libraries?). Fell in love with Lisp at Cleartrip, but sadly had to pivot to Java + Ruby because of lack of mature DB libraries (at the point in time). Now, building a company - Vacation Labs which uses code to solve real-world problems in the travel space. Looking for something better after having written 250,000+ lines of Rails & AngularJS.
TODO
TODO
Started coding on a C64, then later on an Intel 286 and then 486. I mostly used C and Assembler, did some small games and had a brief excursion into the demoscene coding a music tracker and creating some tunes with it.
Came in contact with functional programming during my Masters Degree (General Linguistics and Computer Science) at University, where we used typed lambda calculus to model a natural language syntax / semantics interface.
I've been using Haskell ever since both professionally and for private projects. Additionally, I have experience with professional projects in PureScript, JavaScript, Python, C / C++ and Java.