All Projects → JoelSanchez → Ventas

JoelSanchez / Ventas

Licence: epl-1.0
Clojure ecommerce platform

Programming Languages

clojure
4091 projects
clojurescript
191 projects

Projects that are alternatives of or similar to Ventas

Conduit
Real world application built with ClojureScript + re-frame
Stars: ✭ 422 (+270.18%)
Mutual labels:  reagent, re-frame
Re Frame
A ClojureScript framework for building user interfaces, leveraging React
Stars: ✭ 4,980 (+4268.42%)
Mutual labels:  reagent, re-frame
Re Frame Template
A Leiningen template for creating a re-frame application (client only)
Stars: ✭ 454 (+298.25%)
Mutual labels:  reagent, re-frame
Candy Api
GetCandy E-Commerce API
Stars: ✭ 339 (+197.37%)
Mutual labels:  ecommerce, elasticsearch
Re Pollsive
Re-pollsive is a clojurescript library that handles polling events for re-frame applications
Stars: ✭ 27 (-76.32%)
Mutual labels:  reagent, re-frame
Lein template descjop
A Leiningen template(Clojure/ClojureScript Project) for Web based desktop application with Electron (atom-shell).
Stars: ✭ 394 (+245.61%)
Mutual labels:  reagent, re-frame
Re Frame 10x
A debugging dashboard for re-frame. X-ray vision as tooling.
Stars: ✭ 491 (+330.7%)
Mutual labels:  reagent, re-frame
Korio
Korio: Kotlin cORoutines I/O : Virtual File System + Async/Sync Streams + Async TCP Client/Server + WebSockets for Multiplatform Kotlin 1.3
Stars: ✭ 282 (+147.37%)
Mutual labels:  elasticsearch, websockets
Tincture
Frontend development toolkit for ClojureScript
Stars: ✭ 24 (-78.95%)
Mutual labels:  reagent, re-frame
Re Com
A ClojureScript library of reusable components for Reagent
Stars: ✭ 690 (+505.26%)
Mutual labels:  reagent, re-frame
Status React
a free (libre) open source, mobile OS for Ethereum
Stars: ✭ 3,307 (+2800.88%)
Mutual labels:  reagent, re-frame
Gorilla Notebook
A clojure/clojurescript notebook application/-library based on Gorilla-REPL
Stars: ✭ 73 (-35.96%)
Mutual labels:  reagent, re-frame
Workarea
Workarea is an enterprise-grade Ruby on Rails commerce platform
Stars: ✭ 290 (+154.39%)
Mutual labels:  ecommerce, elasticsearch
Re Frisk
Take full control of re-frame app
Stars: ✭ 396 (+247.37%)
Mutual labels:  reagent, re-frame
Kee Frame
re-frame with batteries included
Stars: ✭ 289 (+153.51%)
Mutual labels:  reagent, re-frame
Open Loyalty
Open Loyalty is technology for loyalty solutions for starting new loyalty projects.
Stars: ✭ 476 (+317.54%)
Mutual labels:  ecommerce, elasticsearch
re-frame-http-fx-alpha
A ClojureScript client library for HTTP requests. Provides a re-frame "effect handler" keyed :http
Stars: ✭ 37 (-67.54%)
Mutual labels:  reagent, re-frame
notebook
Web based Clojure notebook application/-library.
Stars: ✭ 96 (-15.79%)
Mutual labels:  reagent, re-frame
Cljfx
Declarative, functional and extensible wrapper of JavaFX inspired by better parts of react and re-frame
Stars: ✭ 624 (+447.37%)
Mutual labels:  reagent, re-frame
Kuzzle
Open-source Back-end, self-hostable & ready to use - Real-time, storage, advanced search - Web, Apps, Mobile, IoT -
Stars: ✭ 991 (+769.3%)
Mutual labels:  elasticsearch, websockets

ventas

Build Status Clojars Project License

ventas was a WIP ecommerce platform written entirely in Clojure.

Documentation

Motivation

No open source ecommerce project satisfies me. I've been working with most of them for years and I think they suck. I won't name any, but this is roughly what I think about the available solutions:

  • They tend to be difficult to extend or modify. They try to tackle the problem with extension systems, but in the end you need to modify the code of the core to do meaningful changes. This forces you to choose between never updating the software or making an exceptional effort to keep your changes applied. This is why one of the main design decisions for this project is to make it very easy to extend and modify.

  • They tend to be difficult to reason about. Because they are built upon a fundamentally mutable model, it's impossible to know how did the database get to the current state. In the best case, something bad happens and I don't know why. In the worst case, something bad happens and I don't even notice (until it's too late). Having mutable objects everywhere doesn't help either.

  • They tend to have poor performance out of the box. Of course everything can be made performant, but I shouldn't need to make the effort. Particularly when "effort" means rewriting SQL queries, or wasting several days trying to find out what's causing my store to take 20 seconds to load.

  • They tend to be over-engineered, or having user-hostile "features". This is a problem in a lot of software, but it's there nonetheless.

Note that these points don't mean that ventas does not or will not commit the same sins. I just try not to.

Getting started

At the moment, ventas is unfit for its purpose. However, if you are a developer and just want to see the project in action, read on.

You need to have git and leiningen installed. You also need access to a Datomic database and an Elasticsearch instance. (See Setting up a local environment with docker-compose if you feel comfortable with Docker)

First clone the project and cd into it:

$ git clone https://github.com/JoelSanchez/ventas
$ cd ventas

Now you can start the REPL:

$ lein repl

When the REPL is ready, execute init:

user=> (init)
:reloading (ventas.common.utils ventas.utils ventas.config ventas.database ventas.database.schema ventas.database.entity ventas.entities.product-variation ventas.database.generators ventas.entities.i18n ventas.entities.brand ventas.plugin ventas.database.seed ventas.entity-test ventas.events repl ventas.entities.image-size ventas.paths ventas.entities.file ventas.server.ws ventas.logging ventas.server ventas.server-test ventas.auth ventas.entities.user ventas.test-tools ventas.database-test ventas.entities.product-taxonomy ventas.server.pagination ventas.utils.images ventas.server.api ventas.entities.configuration ventas.entities.address ventas.entities.product-term client ventas.plugins.featured-categories.core ventas.plugins.slider.core ventas.entities.order-line ventas.entities.order ventas.common.utils-test ventas.entities.resource ventas.entities.category ventas.entities.product ventas.entities.country ventas.entities.tax ventas.entities.state ventas.plugins.blog.core ventas.plugins.featured-products.core user)
INFO [ventas.database:27] - Starting database, URL: datomic:dev://localhost:4334/ventas
INFO [ventas.server:99] - Starting server
INFO [ventas.server:102] - Starting server on 0.0.0.0:3450
INFO [client:28] - Starting Figwheel
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Compiling "resources/public/files/js/compiled/ventas.js" from ["src/cljs" "src/cljc" "test/cljs" "test/cljc"]...
Successfully compiled "resources/public/files/js/compiled/ventas.js" in 8.252 seconds.
Figwheel: Starting CSS Watcher for paths  ["resources/public/files/css"]
INFO [client:42] - Starting SASS
:done

Then, execute the setup! function, which will migrate the database, install fixtures, etc.:

(ventas.core/setup!)

Now you can open localhost:3450/admin to see the administration. A frontoffice is not included, but you can check out ventas-demo for an example.

To enter the backoffice you'll need to create an admin user for yourself:

(entity/create :user {:first-name "Admin"
                      :email "[email protected]"
                      :password "yourpassword"}

To do frontend development in the backoffice:

lein sass4clj auto
shadow-cljs watch :admin

You can connect to the nREPL server created by shadow-cljs to get a CLJS RPEL:

lein repl :connect localhost:4002
user=> (shadow.cljs.devtools.api/nrepl-select :admin)

Setting up a local environment with Docker Compose

A docker-compose.yaml file is included:

docker-compose up -d

Overview

Backend

  • Written in Clojure.

  • Uses mount and really likes REPL-driven development. Code reload is done by calling repl/r. App initialization is done by calling repl/init.

    ;; (r) reloads changed namespaces, restarts defstates within them, and optionally
    ;; restarts given defstates as keywords
    (r :db)
    INFO [ventas.database:34] - Stopping database
    :reloading ()
    INFO [ventas.database:27] - Starting database, URL: datomic:dev://localhost:4334/ventas
    => :done
    
  • The database is Datomic. A custom database entity system, which relies on core.spec, abstracts the database and allows easy testing and generation of sample data.

    ;; recreates the database, applies the schema, creates the fixtures and seeds the database with randomly generated entities
    (seed/seed :recreate? true :generate? true)
    

    Lots of utility functions make exploring the database and getting data from it more interactive and fast.

     ;; returns a list of active users
    (entity/query :user {:status :user.status/active})
    ;; returns an entity by EID
    (entity/find 17592186045760)
    ;; creates an user and returns the result
    (entity/create :user {:email "[email protected]"
                          :first-name "Test"
                          :last-name "User"})
    ;; generates three users
    (entity/generate :user 3)
    ;; updates an user's company
    (entity/update {:id 17592186045920
                    :company "Test"})
    

    Adding new entities is easy and schema additions are handled behind the curtains (search for calls to entity/register-type! to know more)

  • The HTTP server is http-kit. Routing is handled by Compojure, but they are just 4 handlers, because the actual communication happens over websockets, with the help of chord.

    (register-endpoint!
      :products/get
      (fn [{:keys [params]} state]
        (entity/serialize (entity/find (:id params)))))
    
  • Authentication is done with JWT tokens (provided by buddy).

Frontend

  • Written in ClojureScript, and uses re-frame.

  • Development is done with shadow-cljs.

  • Communication with the server is done using a re-frame effect that abstracts websocket requests. All requests and responses are logged to the verbose level of the JS console, so you can see what's going on.

  • Client-side routing is handled by bidi, but a custom wrapper exists for it, which makes things much easier to deal with.

    (routes/define-route!
     :frontend.product ;; this route is nested inside the :frontend route
     {:name (i18n ::the-name-of-this-page)
      :url ["product/" :id]
      :component a-re-frame-component-for-this-route})
    
  • Stylesheets are written in SCSS. The watcher is also handled by the server's REPL.

  • i18n is done with tongue

  • Semantic UI components.

Contributing

I'd appreciate help in any part of the project.

Please read CONTRIBUTING.md

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].