23 |
About
24 |
25 |
Nullam imperdiet sodales orci vitae molestie. Nunc quam orci, pharetra a rhoncus vitae, eleifend id felis. Suspendisse potenti. Etiam vitae urna orci. Quisque pellentesque dignissim felis, egestas tempus urna luctus vitae. In hac habitasse platea dictumst. Morbi fringilla mattis odio, et mattis tellus accumsan vitae.
26 |
27 | - Amamus Unicode 碁
28 | - Interdum nex magna.
29 |
30 |
Vivamus eget mauris sit amet nulla laoreet lobortis. Nulla in diam elementum risus convallis commodo. Cras vehicula varius dui vitae facilisis. Proin elementum libero eget leo aliquet quis euismod orci vestibulum. Duis rhoncus lorem consequat tellus vestibulum aliquam. Quisque orci orci, malesuada porta blandit et, interdum nec magna.
31 |
32 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/doc/hakyll/_site/archive.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
Archives
24 |
25 | Here you can find all my previous posts:
26 |
41 |
42 |
43 |
44 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/doc/hakyll/_site/contact.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
Contact
24 |
25 |
I live in a small hut in the mountains of Kumano Kodō on Kii Hantō and would not like to be contacted.
26 |
27 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/doc/hakyll/_site/css/default.css:
--------------------------------------------------------------------------------
1 | body{color:black;font-size:16px;margin:0px auto 0px auto;width:800px}code{font-size:14px;background:#f2f2f2;display:inline-block;padding:0px 3px}div#header{border-bottom:2px solid black;margin-bottom:30px;padding:12px 0px 12px 0px}div#logo a{color:black;float:left;font-size:18px;font-weight:bold;text-decoration:none}div#header #navigation{text-align:right}div#header #navigation a{color:black;font-size:18px;font-weight:bold;margin-left:12px;text-decoration:none;text-transform:uppercase}div#footer{border-top:solid 2px black;color:#555;font-size:12px;margin-top:30px;padding:12px 0px 12px 0px;text-align:right}h1{font-size:24px}h2{font-size:20px}div.info{color:#555;font-size:14px;font-style:italic}table{width:100% !important}table th{text-align:left;border-bottom:1px solid #333}table td{border-bottom:1px solid #ccc;vertical-align:top;padding:2px 4px;width:auto}div.sourceCode{font-size:14px;background:#f9f9f9;padding:10px;max-height:300px;overflow-y:scroll;display:block}table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre, .sourceCode{margin:0;padding:0;border:0;border:none}code.sourceCode{background:transparent;display:inline}td.lineNumbers{border-right:1px solid #AAAAAA;text-align:right;color:#AAAAAA;padding-right:5px;padding-left:5px}td.sourceCode{padding-left:5px}.sourceCode span.kw{color:#007020;font-weight:bold}.sourceCode span.dt{color:#902000}.sourceCode span.dv{color:#40a070}.sourceCode span.bn{color:#40a070}.sourceCode span.fl{color:#40a070}.sourceCode span.ch{color:#4070a0}.sourceCode span.st{color:#4070a0}.sourceCode span.co{color:#60a0b0;font-style:italic}.sourceCode span.ot{color:#007020}.sourceCode span.al{color:red;font-weight:bold}.sourceCode span.fu{color:#06287e}.sourceCode span.re{}.sourceCode span.er{color:red;font-weight:bold}
--------------------------------------------------------------------------------
/doc/hakyll/_site/images/haskell-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/doc/hakyll/_site/images/haskell-logo.png
--------------------------------------------------------------------------------
/doc/hakyll/_site/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
Home
24 |
25 |
Comparing Haskell DB libraries
26 |
27 |

28 |
29 |
Welcome to my blog!
30 |
31 |
I've reproduced a list of recent posts here for your reading pleasure:
32 |
33 |
Posts
34 |
49 |
50 |
51 |
…or you can find more in the archives.
52 |
53 |
54 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/doc/hakyll/_site/posts/overview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
Comparison between Opaleye, Haskell Relational Record, and Persistent
24 |
25 |
26 | Posted on November 23, 2016
27 |
28 |
29 |
30 |
Content outline
31 |
32 | - Philosophy and guiding principles behind the libraries
33 |
34 | - Opaleye
35 | - HRR
36 | - Persistent
37 |
38 | - Setting up basic DB mappings - Overview
39 |
40 | - Opalaye
41 | - Persistent
42 |
43 | - Recommended way is Template Haskell
44 |
45 | - HRR
46 |
47 | - Uses TemplateHaskell to fetch the DB definition at compile-time and generate the record types
48 |
49 |
50 | - Setting up advanced DB mappings
51 |
52 | - ENUMs
53 | - Postgres arrays
54 | - JSONB
55 | - Non-integer primary keys
56 |
57 | - DSL support for other SQL stuff
58 |
59 | - Constraints (CHECK & REFERENCES)
60 | - Triggers
61 | - Opaleye
62 |
63 | - Doesn’t give DSL for DDL (data definition language) commands in SQL
64 |
65 | - Persistent
66 |
67 | - How to run custom SQL in-sync with the automatic migration?
68 |
69 | - HRR
70 |
73 |
74 | - Inserting rows
75 |
76 | - Specifying all columns in the row
77 | - Omitting certain columns and letting DB specify the default
78 | INSERT... RETURNING ID
79 | INSERT... RETURNING *
80 | - Insert single row
81 | - Insert multiple rows
82 |
83 | - Updating rows
84 |
85 | - Updating all columns in matching row(s)
86 | - Updating only specific columns in matching row(s)
87 | - Updates with JOINs
88 | UPDATE... RETURNING *
89 |
90 | - Selecting rows
91 |
92 | - Simple select of single row
93 | - Fetch all columns from rows matching a condition
94 | - Fetch specific columns from rows matching a condition
95 | - Ordering
96 | - Grouping
97 | - Joins
98 | - Limit/offset
99 | - Selecting in batches (or using cursors)
100 |
101 | - Database transactions
102 |
103 | - Nested DB transactions
104 |
105 | - Managing housekeeping columns (createdAt, updatedAt)
106 | - Support for prepared statements
107 | - Any special/interesting/unique features?
108 |
109 |
110 |
111 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/doc/hakyll/about.rst:
--------------------------------------------------------------------------------
1 | ---
2 | title: About
3 | ---
4 | Nullam imperdiet sodales orci vitae molestie. Nunc quam orci, pharetra a
5 | rhoncus vitae, eleifend id felis. Suspendisse potenti. Etiam vitae urna orci.
6 | Quisque pellentesque dignissim felis, egestas tempus urna luctus vitae. In hac
7 | habitasse platea dictumst. Morbi fringilla mattis odio, et mattis tellus
8 | accumsan vitae.
9 |
10 | 1. Amamus Unicode 碁
11 | 2. Interdum nex magna.
12 |
13 | Vivamus eget mauris sit amet nulla laoreet lobortis. Nulla in diam elementum
14 | risus convallis commodo. Cras vehicula varius dui vitae facilisis. Proin
15 | elementum libero eget leo aliquet quis euismod orci vestibulum. Duis rhoncus
16 | lorem consequat tellus vestibulum aliquam. Quisque orci orci, malesuada porta
17 | blandit et, interdum nec magna.
18 |
--------------------------------------------------------------------------------
/doc/hakyll/contact.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | title: Contact
3 | ---
4 |
5 | I live in a small hut in the mountains of Kumano Kodō on Kii Hantō and would not
6 | like to be contacted.
7 |
--------------------------------------------------------------------------------
/doc/hakyll/css/default.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: black;
3 | font-size: 16px;
4 | margin: 0px auto 0px auto;
5 | width: 800px;
6 | }
7 |
8 | code {
9 | font-size: 14px;
10 | background: #f2f2f2;
11 | display: inline-block;
12 | padding: 0px 3px;
13 | }
14 |
15 | div#header {
16 | border-bottom: 2px solid black;
17 | margin-bottom: 30px;
18 | padding: 12px 0px 12px 0px;
19 | }
20 |
21 | div#logo a {
22 | color: black;
23 | float: left;
24 | font-size: 18px;
25 | font-weight: bold;
26 | text-decoration: none;
27 | }
28 |
29 | div#header #navigation {
30 | text-align: right;
31 | }
32 |
33 | div#header #navigation a {
34 | color: black;
35 | font-size: 18px;
36 | font-weight: bold;
37 | margin-left: 12px;
38 | text-decoration: none;
39 | text-transform: uppercase;
40 | }
41 |
42 | div#footer {
43 | border-top: solid 2px black;
44 | color: #555;
45 | font-size: 12px;
46 | margin-top: 30px;
47 | padding: 12px 0px 12px 0px;
48 | text-align: right;
49 | }
50 |
51 | h1 {
52 | font-size: 24px;
53 | }
54 |
55 | h2 {
56 | font-size: 20px;
57 | }
58 |
59 | div.info {
60 | color: #555;
61 | font-size: 14px;
62 | font-style: italic;
63 | }
64 |
65 | table {
66 | width: 100% !important;
67 | }
68 |
69 | table th {
70 | text-align: left;
71 | border-bottom: 1px solid #333;
72 | }
73 | table td {
74 | border-bottom: 1px solid #ccc;
75 | vertical-align: top;
76 | padding: 2px 4px;
77 | width: auto;
78 | }
79 |
80 | /* Generated by pandoc. - HASKELL SYNTAX HIGHLIGHTING */
81 | div.sourceCode {
82 | font-size: 14px;
83 | background: #f9f9f9;
84 | padding: 10px;
85 | max-height: 300px;
86 | overflow-y: scroll;
87 | display: block;
88 | }
89 | table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre, .sourceCode {
90 | margin: 0;
91 | padding: 0;
92 | border: 0;
93 | border: none;
94 | }
95 |
96 | code.sourceCode {
97 | background: transparent;
98 | display: inline;
99 | }
100 |
101 | td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
102 | td.sourceCode { padding-left: 5px; }
103 | .sourceCode span.kw { color: #007020; font-weight: bold; }
104 | .sourceCode span.dt { color: #902000; }
105 | .sourceCode span.dv { color: #40a070; }
106 | .sourceCode span.bn { color: #40a070; }
107 | .sourceCode span.fl { color: #40a070; }
108 | .sourceCode span.ch { color: #4070a0; }
109 | .sourceCode span.st { color: #4070a0; }
110 | .sourceCode span.co { color: #60a0b0; font-style: italic; }
111 | .sourceCode span.ot { color: #007020; }
112 | .sourceCode span.al { color: red; font-weight: bold; }
113 | .sourceCode span.fu { color: #06287e; }
114 | .sourceCode span.re { }
115 | .sourceCode span.er { color: red; font-weight: bold; }
--------------------------------------------------------------------------------
/doc/hakyll/doc.cabal:
--------------------------------------------------------------------------------
1 | name: doc
2 | version: 0.1.0.0
3 | build-type: Simple
4 | cabal-version: >= 1.10
5 |
6 | executable site
7 | main-is: site.hs
8 | build-depends: base == 4.*
9 | , hakyll == 4.8.*
10 | ghc-options: -threaded
11 | default-language: Haskell2010
12 |
--------------------------------------------------------------------------------
/doc/hakyll/images/haskell-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/doc/hakyll/images/haskell-logo.png
--------------------------------------------------------------------------------
/doc/hakyll/includes/db-mappings/DB.hs:
--------------------------------------------------------------------------------
1 | module DB where
2 |
3 | import Opalaye
4 | import Data.Text
5 | import Data.Time (UTCTime)
6 |
7 | data TenantPoly key createdAt updatedAt name status ownerId backofficeDomain = Tenant {
8 | tenantKey :: key
9 | ,tenantCreatedAt :: createdAt
10 | ,tenantUpdatedAt :: updatedAt
11 | ,tenantName :: name
12 | ,tenantStatus :: status
13 | ,tenantOwnerId :: ownerId
14 | ,tenantBackofficeDomain :: backofficeDomain
15 | } deriving Show
16 |
17 | type TenantPGWrite = TenantPoly
18 | (Maybe (Column PGInt8)) -- key
19 | (Maybe (Column PGTimestamptz)) -- createdAt
20 | (Column PGTimestamptz) -- updatedAt
21 | (Column PGText) -- name
22 | (Column PGText) -- status
23 | (Column (Nullable PGInt8)) -- ownerId
24 | (Column PGText) -- backofficeDomain
25 |
26 | type TenantPGRead = TenantPoly
27 | (Column PGInt8) -- key
28 | (Column PGTimestamptz) -- createdAt
29 | (Column PGTimestamptz) -- updatedAt
30 | (Column PGText) -- name
31 | (Column PGText) -- status
32 | (Column (Nullable PGInt8)) -- ownerId
33 | (Column PGText) -- backofficeDomain
34 |
35 | type Tenant = TenantPoly
36 | Integer -- key
37 | UTCTime -- createdAt
38 | UTCTime -- updatedAt
39 | Text -- name
40 | Text -- status
41 | (Maybe Integer) -- ownerId
42 | Text -- backofficeDomain
43 |
44 | $(makeAdaptorAndInstance "pTenant" ''TenantPoly)
45 | $(makeLensesWith abbreviatedFields ''TenantPoly)
46 |
47 |
48 | tenantTable :: Table TenantPGWrite TenantPGRead
49 | tenantTable = Table "tenants" (pTenant Tenant{
50 | tenantKey = optional "id"
51 | ,tenantCreatedAt = optional "created_at"
52 | ,tenantUpdatedAt = required "updated_at"
53 | ,tenantName = required "name"
54 | ,tenantStatus = required "status"
55 | ,tenantOwnerId = required "owner_id"
56 | ,tenantBackofficeDomain = required "backoffice_domain"
57 | })
--------------------------------------------------------------------------------
/doc/hakyll/includes/db-mappings/schema.sql:
--------------------------------------------------------------------------------
1 | --
2 | -- Tenants
3 | --
4 |
5 | create table tenants(
6 | id serial primary key
7 | ,created_at timestamp with time zone not null default current_timestamp
8 | ,updated_at timestamp with time zone not null default current_timestamp
9 | ,name text not null
10 | ,first_name text not null
11 | ,last_name text not null
12 | ,email text not null
13 | ,phone text not null
14 | ,status text not null default 'inactive'
15 | ,owner_id integer
16 | ,backoffice_domain text not null
17 | constraint ensure_not_null_owner_id check (status!='active' or owner_id is not null)
18 | );
19 | create unique index idx_index_owner_id on tenants(owner_id);
20 | create index idx_status on tenants(status);
21 | create index idx_tenants_created_at on tenants(created_at);
22 | create index idx_tenants_updated_at on tenants(updated_at);
23 | create unique index idx_unique_tenants_backoffice_domain on tenants(lower(backoffice_domain));
24 |
--------------------------------------------------------------------------------
/doc/hakyll/index.html:
--------------------------------------------------------------------------------
1 | ---
2 | title: Home
3 | ---
4 |
5 |
2 | Posted on $date$
3 | $if(author)$
4 | by $author$
5 | $endif$
6 |
7 |
8 | $body$
9 |
--------------------------------------------------------------------------------
/doc/index.rst:
--------------------------------------------------------------------------------
1 | .. Haskell Tutorials documentation master file, created by
2 | sphinx-quickstart on Thu Nov 24 09:36:10 2016.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Haskell Tutorials
7 | =================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 | docs/opaleye/opaleye
15 | docs/reflex/reflex
16 | docs/framework/index
17 |
--------------------------------------------------------------------------------
/skeleton/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright Author name here (c) 2016
2 |
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 |
11 | * Redistributions in binary form must reproduce the above
12 | copyright notice, this list of conditions and the following
13 | disclaimer in the documentation and/or other materials provided
14 | with the distribution.
15 |
16 | * Neither the name of Author name here nor the names of other
17 | contributors may be used to endorse or promote products derived
18 | from this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/skeleton/Setup.hs:
--------------------------------------------------------------------------------
1 | import Distribution.Simple
2 | main = defaultMain
3 |
--------------------------------------------------------------------------------
/skeleton/app/Main.hs:
--------------------------------------------------------------------------------
1 | module Main where
2 |
3 | import Lib
4 |
5 | main :: IO ()
6 | main = someFunc
7 |
--------------------------------------------------------------------------------
/skeleton/skeleton.cabal:
--------------------------------------------------------------------------------
1 | name: skeleton
2 | version: 0.1.0.0
3 | synopsis: Initial project template from stack
4 | description: Please see README.md
5 | homepage: https://github.com/githubuser/skeleton#readme
6 | license: BSD3
7 | license-file: LICENSE
8 | author: Author name here
9 | maintainer: example@example.com
10 | copyright: 2016 Author name here
11 | category: Web
12 | build-type: Simple
13 | -- extra-source-files:
14 | cabal-version: >=1.10
15 |
16 | library
17 | hs-source-dirs: src
18 | exposed-modules: Lib
19 | build-depends: base >= 4.7 && < 5
20 | , text
21 | , mtl
22 | , time
23 | , transformers
24 | , bytestring
25 | , lens
26 |
27 | default-language: Haskell2010
28 |
29 | executable skeleton-exe
30 | hs-source-dirs: app
31 | main-is: Main.hs
32 | ghc-options: -threaded -rtsopts -with-rtsopts=-N
33 | build-depends: base
34 | , skeleton
35 | default-language: Haskell2010
36 |
37 | test-suite skeleton-test
38 | type: exitcode-stdio-1.0
39 | hs-source-dirs: test
40 | main-is: Spec.hs
41 | build-depends: base
42 | , skeleton
43 | ghc-options: -threaded -rtsopts -with-rtsopts=-N
44 | default-language: Haskell2010
45 |
46 | source-repository head
47 | type: git
48 | location: https://github.com/githubuser/skeleton
49 |
--------------------------------------------------------------------------------
/skeleton/src/Domain/Auth.hs:
--------------------------------------------------------------------------------
1 | module Domain.Auth where
2 |
3 | import Import
4 | import Domain.Types
5 |
6 | authenticateUser :: Text -> Text -> AppM(Bool)
7 | authenticateUser username password = undefined
8 |
9 | -- TODO: Should the domain API be dealing with sessions? Or should it be handled
10 | -- by a layer sitting on top of Domain.Auth
11 |
12 | createSession :: Text -> Text -> AppM(SessionID)
13 | createSession username password = undefined
14 |
15 | destroySession :: SessionID -> AppM()
16 | destroySession sessid = undefined
17 |
18 |
--------------------------------------------------------------------------------
/skeleton/src/Domain/Photo.hs:
--------------------------------------------------------------------------------
1 | module Domain.Photo where
2 |
3 | import Import
4 | import Domain.Types
5 |
6 | createPhoto :: ByteString -> AppM(Photo)
7 | createPhoto bstring = undefined
8 |
9 | removePhoto :: PhotoID -> AppM()
10 | remotePhoto pid = undefined
11 |
12 | getPhoto :: PhotoID -> Text -> AppM(Photo)
13 | getPhoto pid geometryOrStyle = undefined
14 |
--------------------------------------------------------------------------------
/skeleton/src/Domain/Product.hs:
--------------------------------------------------------------------------------
1 | module Domain.Product where
2 |
3 | import Import
4 | import Domain.Types
5 |
6 | createProduct :: Product -> AppM(Product)
7 | createProduct product = undefined
8 |
9 | editProduct :: Product -> AppM(Product)
10 | editProduct product = undefined
11 |
12 | getProduct :: ProductID -> AppM(Product)
13 | getProduct pid = undefined
14 |
15 |
16 | data ProductFilter = ProductFilter { ids :: [ProductID]
17 | , q :: Text
18 | , title :: Text
19 | -- and more such filters can come here
20 | }
21 | filterProducts :: ProductFilter -> AppM([Product])
22 | filterProducts pfilter = undefined
23 |
--------------------------------------------------------------------------------
/skeleton/src/Domain/Role.hs:
--------------------------------------------------------------------------------
1 | module Domain.Role where
2 |
3 | import Import
4 | import Domain.Types
5 |
6 | createRole :: Role -> AppM(Role)
7 | createRole role = undefined
8 |
9 | getRole :: RoleID -> AppM(Role)
10 | getRole rid = undefined
11 |
--------------------------------------------------------------------------------
/skeleton/src/Domain/Tenant.hs:
--------------------------------------------------------------------------------
1 | module Domain.Tenant where
2 |
3 | import Import
4 | import Domain.Types
5 |
6 | createTenant :: Tenant -> AppM(Tenant)
7 | createTenant tenant = undefined
8 |
9 | activateTenant :: Tenant -> Text -> AppM(Tenant)
10 | activateTenant tenant activationKey = undefined
11 |
12 | getTenant :: TenantID -> AppM(Tenant)
13 | getTenant tid = undefined
14 |
15 |
--------------------------------------------------------------------------------
/skeleton/src/Domain/Types.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE TemplateHaskell #-}
2 | module Types where
3 |
4 | import Import
5 |
6 | data AppConfig = AppConfig { dbPool :: Text
7 | , redisPool :: Text
8 | }
9 | type AppM = ReaderT AppConfig
10 |
11 | type TenantID = Integer
12 | data Tenant = Tenant{}
13 |
14 | type UserID = Integer
15 | data User = User{}
16 |
17 | type ProductID = Integer
18 | data Product = Product{}
19 |
20 | type VariantID = Integer
21 | data Variant = Variant{}
22 |
23 | type PhotoID = Integer
24 | data Photo = Photo{}
25 |
26 | type RoleID = Integer
27 | data Role = Role{}
28 |
29 | type AuditLogID = Integer
30 | data AuditLog = AuditLog{}
31 |
32 | type SessionID = Text
33 |
34 | -- LENSES
35 | $(makeClassy ''AppConfig)
36 | $(makeClassy ''Tenant)
37 | $(makeClassy ''User)
38 | $(makeClassy ''Role)
39 | $(makeClassy ''Product)
40 | $(makeClassy ''Variant)
41 | $(makeClassy ''Photo)
42 | $(makeClassy ''AuditLog)
43 |
--------------------------------------------------------------------------------
/skeleton/src/Domain/User.hs:
--------------------------------------------------------------------------------
1 | module Domain.User where
2 |
3 | import Import
4 | import Domain.Types
5 |
6 | createUser :: User -> AppM(User)
7 | createUser user = undefined
8 |
9 | activateUser :: User -> Text -> AppM(User)
10 | activateUser user activationKey = undefined
11 |
12 | deactivateUser :: User -> AppM(User)
13 | deactivateUser user = undefined
14 |
15 | getUser :: UserID -> AppM(User)
16 | getUser uid = undefined
17 |
18 |
--------------------------------------------------------------------------------
/skeleton/src/Import.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE TemplateHaskell #-}
2 | module Import( ReaderT
3 | , Text
4 | , ByteString
5 | , module Control.Lens
6 | ) where
7 |
8 | import Control.Monad.Reader (ReaderT)
9 | import Data.Text (Text)
10 | import Data.ByteString (ByteString)
11 | import Control.Lens
12 |
--------------------------------------------------------------------------------
/skeleton/src/Lib.hs:
--------------------------------------------------------------------------------
1 | module Lib
2 | ( someFunc
3 | ) where
4 |
5 | someFunc :: IO ()
6 | someFunc = putStrLn "someFunc"
7 |
--------------------------------------------------------------------------------
/skeleton/stack.yaml:
--------------------------------------------------------------------------------
1 | # This file was automatically generated by 'stack init'
2 | #
3 | # Some commonly used options have been documented as comments in this file.
4 | # For advanced use and comprehensive documentation of the format, please see:
5 | # http://docs.haskellstack.org/en/stable/yaml_configuration/
6 |
7 | # Resolver to choose a 'specific' stackage snapshot or a compiler version.
8 | # A snapshot resolver dictates the compiler version and the set of packages
9 | # to be used for project dependencies. For example:
10 | #
11 | # resolver: lts-3.5
12 | # resolver: nightly-2015-09-21
13 | # resolver: ghc-7.10.2
14 | # resolver: ghcjs-0.1.0_ghc-7.10.2
15 | # resolver:
16 | # name: custom-snapshot
17 | # location: "./custom-snapshot.yaml"
18 | resolver: lts-7.4
19 |
20 | # User packages to be built.
21 | # Various formats can be used as shown in the example below.
22 | #
23 | # packages:
24 | # - some-directory
25 | # - https://example.com/foo/bar/baz-0.0.2.tar.gz
26 | # - location:
27 | # git: https://github.com/commercialhaskell/stack.git
28 | # commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
29 | # - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
30 | # extra-dep: true
31 | # subdirs:
32 | # - auto-update
33 | # - wai
34 | #
35 | # A package marked 'extra-dep: true' will only be built if demanded by a
36 | # non-dependency (i.e. a user package), and its test suites and benchmarks
37 | # will not be run. This is useful for tweaking upstream packages.
38 | packages:
39 | - '.'
40 | # Dependency packages to be pulled from upstream that are not in the resolver
41 | # (e.g., acme-missiles-0.3)
42 | extra-deps: []
43 |
44 | # Override default flag values for local packages and extra-deps
45 | flags: {}
46 |
47 | # Extra package databases containing global packages
48 | extra-package-dbs: []
49 |
50 | # Control whether we use the GHC we find on the path
51 | # system-ghc: true
52 | #
53 | # Require a specific version of stack, using version ranges
54 | # require-stack-version: -any # Default
55 | # require-stack-version: ">=1.1"
56 | #
57 | # Override the architecture used by stack, especially useful on Windows
58 | # arch: i386
59 | # arch: x86_64
60 | #
61 | # Extra directories used by stack for building
62 | # extra-include-dirs: [/path/to/dir]
63 | # extra-lib-dirs: [/path/to/dir]
64 | #
65 | # Allow a newer minor version of GHC than the snapshot specifies
66 | # compiler-check: newer-minor
--------------------------------------------------------------------------------
/skeleton/test/Spec.hs:
--------------------------------------------------------------------------------
1 | main :: IO ()
2 | main = putStrLn "Test suite not yet implemented"
3 |
--------------------------------------------------------------------------------
/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/ui-mockups/assets/css/Login-Form-Clean.css:
--------------------------------------------------------------------------------
1 | .login-clean {
2 | background:#f1f7fc;
3 | padding:80px 0;
4 | }
5 |
6 | .login-clean form {
7 | max-width:320px;
8 | width:90%;
9 | margin:0 auto;
10 | background-color:#ffffff;
11 | padding:40px;
12 | border-radius:4px;
13 | color:#505e6c;
14 | box-shadow:1px 1px 5px rgba(0,0,0,0.1);
15 | }
16 |
17 | .login-clean .illustration {
18 | text-align:center;
19 | padding:0 0 20px;
20 | font-size:100px;
21 | color:rgb(244,71,107);
22 | }
23 |
24 | .login-clean form .form-control {
25 | background:#f7f9fc;
26 | border:none;
27 | border-bottom:1px solid #dfe7f1;
28 | border-radius:0;
29 | box-shadow:none;
30 | outline:none;
31 | color:inherit;
32 | text-indent:8px;
33 | height:42px;
34 | }
35 |
36 | .login-clean form .btn-primary {
37 | background:#f4476b;
38 | border:none;
39 | border-radius:4px;
40 | padding:11px;
41 | box-shadow:none;
42 | margin-top:26px;
43 | text-shadow:none;
44 | outline:none !important;
45 | }
46 |
47 | .login-clean form .btn-primary:hover, .login-clean form .btn-primary:active {
48 | background:#eb3b60;
49 | }
50 |
51 | .login-clean form .btn-primary:active {
52 | transform:translateY(1px);
53 | }
54 |
55 | .login-clean form .forgot {
56 | display:block;
57 | text-align:center;
58 | font-size:12px;
59 | color:#6f7a85;
60 | opacity:0.9;
61 | text-decoration:none;
62 | }
63 |
64 | .login-clean form .forgot:hover, .login-clean form .forgot:active {
65 | opacity:1;
66 | text-decoration:none;
67 | }
68 |
69 |
--------------------------------------------------------------------------------
/ui-mockups/assets/css/styles.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/css/styles.css
--------------------------------------------------------------------------------
/ui-mockups/assets/css/styles.min.css:
--------------------------------------------------------------------------------
1 | h1.page-heading{border-bottom:1px solid #ccc;margin-bottom:20px;padding-bottom:5px}a.cancel{margin-left:10px}div.secton-menu{background-color:#ffc;padding:0}.login-clean{background:#f1f7fc;padding:80px 0}.login-clean form{max-width:320px;width:90%;margin:0 auto;background-color:#fff;padding:40px;border-radius:4px;color:#505e6c;box-shadow:1px 1px 5px rgba(0,0,0,.1)}.login-clean .illustration{text-align:center;padding:0 0 20px;font-size:100px;color:#f4476b}.login-clean form .form-control{background:#f7f9fc;border:none;border-bottom:1px solid #dfe7f1;border-radius:0;box-shadow:none;outline:0;color:inherit;text-indent:8px;height:42px}.login-clean form .btn-primary{background:#f4476b;border:none;border-radius:4px;padding:11px;box-shadow:none;margin-top:26px;text-shadow:none;outline:0!important}.login-clean form .btn-primary:active,.login-clean form .btn-primary:hover{background:#eb3b60}.login-clean form .btn-primary:active{transform:translateY(1px)}.login-clean form .forgot{display:block;text-align:center;font-size:12px;color:#6f7a85;opacity:.9;text-decoration:none}.login-clean form .forgot:active,.login-clean form .forgot:hover{opacity:1;text-decoration:none}form.login-form{margin:0 auto;display:block}div.checkbox.permission-group-heading{border-bottom:1px solid #ccc;margin-bottom:15px;padding-bottom:3px}
--------------------------------------------------------------------------------
/ui-mockups/assets/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/fonts/ionicons.eot
--------------------------------------------------------------------------------
/ui-mockups/assets/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/ui-mockups/assets/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vacationlabs/haskell-webapps/7cbc95646693e105798b7bc0ce64602ef91be196/ui-mockups/assets/fonts/ionicons.woff
--------------------------------------------------------------------------------
/ui-mockups/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |