FIND A GAME

MOBILE APPLICATION
The social network for golfers to find partners for the game, host games, and find suitable golf courses.

Golf clubs can sell game passes directly in the app and quickly receive payments to their accounts.

WE USED CLOJURE
FOR THIS PROJECT

Clojure allowed us

to put Cypher requests to a separate file instead of writing them in lines
To simplify writing the queries in the database, due to the syntax support by the development environment and the rejection of extra characters (for example, the end of line character)

Specific solutions were implemented in Clojure

Clojure was used for the custom parser of CQL query files (Cypher Query Language), as well as for the corresponding model function generator, which was running over DBMS Neo4j

Clojure benefits for this project

reducing time of the mobile app development
improving readability, because code with the different syntax was in separate files
possibility of moving to another DBMS without major changes to the Clojure code, due to the separation of the description of the model functions and its implementation

Code example

(ns top500golf.graph.utils 
  (:require [top500golf.data :refer [course-list golfer-list contact-list golfer-courses]]
           [clojurewerkz.neocons.rest.cypher :as cy]
           [clojurewerkz.neocons.rest.nodes :as nn]
            [clojurewerkz.neocons.rest.transaction :as tx]
           [clojurewerkz.neocons.rest.labels :as nl]
            [clojurewerkz.neocons.rest.relationships :as nr]
           [environ.core :refer [env]]
            [clojure.string :as str])
(:use [top500golf.common]
      [top500golf.graph.parser]
      [clojurewerkz.neocons.rest.records]
      [top500golf.graph])
(:import (java.util Date List) 
          (clojurewerkz.neocons.rest.records Node)))

(defn cypher->
[^String query]
(cy/tquery connection query))

(defn create-root-var
"Given a name and a value, intern a var in the current namespace, taking metadata from the value."
([name value]
  (create-root-var *ns* name value))

([ns name value]
  (intern *ns*
         (with-meta (symbol name)
           (meta value))
          value)))


(defn generate-prepare-query-fn
"It does not assert anything, just a wrapper which executes prepare-query  
  so it can be used as a function with a name = query name, specified with //name"
[{:keys [name statement] :as query-string}] 
(fn [parameter-map]
   (let [execute-fn
          (condp = (last name)
            \ > u/cypher->v
            \! u/cypher->)]
     (-> statement
        (statement-parser/prepare-query parameter-map)
         execute-fn))))
‍
(defn parse-tagged-queries
  [text]
  (iu/process-instaparse-result
    (instaparse/transform
       parser-transforms
       (instaparse/parses
         parser (str text "\n")
         :start :queries))
{}))

(defn defqueries 
 [filename] 
 (->> filename
      (str "queries/")
      (io/resource)
      slurp
      parse-tagged-queries
      (map gen/generate-var)
      doall))

* user.cql
//name: user:find-user-by-reset-pw-key>
match (c:Golfer {resetpw : @resetpw}) return c limit 1;

* user.clj
(qp/defqueries "user.cql")
(defn find-user-by-reset-pw-key [reset-pw-key] 
  (-> (user:find-user-by-reset-pw-key> {:resetpw reset-pw-key})     first get-map))

THE CLIENT'S REQUIREMENTS

COMMERCIAL

A stable and high performance application
An implementation of a significant number of new features
A senior developer to start implementation as quickly as possible
Numerous adjustments to individual user data sets in the DBMS

TECHNICAL

A complete code refactoring, since the application was unstable and regularly crashed
Complete data migration from the existing DBMS to a new database while maintaining its integrity and structure, as well as optimizing the data structure in the DBMS to reduce the size of the database and increase the data handling speed

WE RECEIVED FOR IMPROVEMENT

1
Slow and unstable product
2
Application with a few working features
3
Code riddled with errors and suboptimal structure in need of full refactoring and optimization
4
Suboptimal database handling algorithms, which resulted in inefficient use of server capacity and additional maintenance expenses
Challenges for the FreshCode team

The entire code of the project was compiled in two files. Full code refactoring was necessary to eliminate errors and establish optimal structure;

Migration to a new DBMS was performed for an active application with a full data transfer from the old database. To secure data integrity and structure, the developer created a new & unique algorithm for parsing DBMS queries;

The algorithms for data computing, sorting & grouping were in need of optimization. The developer wrote a separate, complex algorithm for handling data.

Let us estimate your project

alex slobozhan

ALEX SLOBOZHAN

SOLUTIONS

find a game case
find a game freshcode
mobile app development
social network app
social network development
social network application

FEATURE SET

1
Registration of golf club customers, including sign up with Facebook profiles
2
Internal messenger
3
Player search throughout the user's phonebook and among the contacts of the user's friends
4
Opponent selection by the desired difficulty level
5
Golf game hosting features:
  • set the game's date and time;
  • select of the course for the game;
  • leave comments;
  • choose the opponents for the game;
  • invite specific players to the game;
  • pay for the selected game course directly from the application;
  • create and update the game score tables;
6
Playing schedule for 14 days
7
SMS notifications
We created the application using React Native and added custom native components written directly on Objective-C, Swift (for iOS) and Java, Kotlin (for Android).
Backend & Database
Clojure, Neo4j
External services
GCM, APNs
Frontend
React Native, Objective-C, Swift (for iOS), Java & Kotlin (for Android)
Deployment
Docker
Currently, the project is at the beta-testing stage

SOLVED PROBLEMS

COMMERCIAL

A transition to a new database ensured stable operation of the application without crashes
Optimization and writing of new algorithms for DBMS handling increased the speed of interaction with the database times 10. All data adjustments required by the client were accomplished
Optimization of the application reduced technical requirements for the servers and resulted in maintenance savings
The application was supplemented by a wide range of new functions, all features required by the client were implemented
Within two days, we provided the client with a senior developer ready to start the development
The client could change the team dynamically, FreshCode was prepared to offer new developers for the project at any moment

TECHNICAL

The code refactoring created a simple and user-friendly structure and eliminated errors. Handling the application code became clear and simple for developers of any level (from senior to junior)
Complete data migration from an old database to a new one was performed. The stored data was optimized reducing the database size without data losses

LESSONS LEARNED

Everyday we work hard to make life of our clients better and happier
Project Duration
1 year and 9 months
Team
1 senior developer working full time
Services rendered
Backend development for a mobile application

STAGES OF COOPERATION

Carefully studied the client's requirements
1
2
Devised the project implementation plan
Implemented all requirements
3
4
Regularly interacted with the client, provided status updates and interim demos

Get a free consult on the current quality of your project and its improvement possibilities

anchor