Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Commit

Permalink
API framework
Browse files Browse the repository at this point in the history
  • Loading branch information
Shpigford committed Jan 8, 2024
1 parent a88ece6 commit 5b93e9e
Show file tree
Hide file tree
Showing 18 changed files with 239 additions and 30 deletions.
10 changes: 5 additions & 5 deletions app/assets/stylesheets/application.tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
@tailwind components;
@tailwind utilities;

/*
@layer components {
.btn-primary {
@apply py-2 px-4 bg-blue-200;
@apply bg-blue-400 hover:bg-blue-500 border border-blue-500 text-white text-sm px-3 py-1.5 rounded-[10px] text-center;
}
}

*/
.btn-secondary {
@apply bg-white hover: bg-gray-50 border border-gray-200 text-black text-sm px-3 py-1.5 rounded-[10px] text-center;
}
}
11 changes: 11 additions & 0 deletions app/models/api_key.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ApiKey < ApplicationRecord
belongs_to :user

before_create :generate_key

private

def generate_key
self.key = SecureRandom.hex(20)
end
end
1 change: 1 addition & 0 deletions app/models/exchange.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Exchange < ApplicationRecord
has_many :operating_hours
has_many :holidays
has_many :transactions, as: :transactable, dependent: :destroy
end
11 changes: 11 additions & 0 deletions app/models/transaction.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Transaction < ApplicationRecord
belongs_to :user
belongs_to :transactable, polymorphic: true, optional: true

after_create :update_user_balance

def update_user_balance
user.balance += self.amount
user.save
end
end
41 changes: 41 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ class User < ApplicationRecord
:confirmable, :lockable, :trackable, :omniauthable,
omniauth_providers: %i[google_oauth2 github]

has_many :api_keys, dependent: :destroy
has_many :transactions, dependent: :destroy

after_create :generate_first_api_key
after_create :add_starting_credits

def self.from_omniauth(auth, referral = nil)
find_or_create_by(provider: auth.provider, uid: auth.uid) do |user|
user.email = auth.info.email
Expand All @@ -24,4 +30,39 @@ def self.from_omniauth(auth, referral = nil)
end
end

def charge_credits(amount, transactable)
if self.balance >= amount
Transaction.create!(
user: self,
amount: -amount,
transaction_timestamp: Time.now,
transactable: transactable
)
true
else
false
end
end

def add_credits(amount)
Transaction.create!(
user: self,
amount: amount,
transaction_timestamp: Time.now
)
end

def key
self.api_keys.first.key
end

private

def generate_first_api_key
self.api_keys.create
end

def add_starting_credits
self.add_credits(250)
end
end
2 changes: 1 addition & 1 deletion app/views/devise/sessions/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<%= button_to "#{image_tag('logo-github.svg', class:'w-5 h-5 align-middle inline-block mr-2')} Continue with GitHub".html_safe, user_github_omniauth_authorize_path, class: "font-medium inline-flex justify-center w-full items-center px-3 py-3 bg-white rounded-lg shadow-sm text-gray-900 ring-1 ring-inset ring-gray-200 hover:bg-gray-50 focus:outline-offset-0", method: :post, "data-turbo": false, form_class: "inline" %>
</div>
<div class="text-xs leading-4 text-center text-gray-400">
By signing up, you acknowledge that you have read, understood, and agree to Maybe's <a href="https://maybe.co/terms" class="text-caribbean-green-500">Terms & Conditions</a> and <a href="https://maybe.co/privacy" class="text-caribbean-green-500">Privacy Policy</a>.
By signing up, you acknowledge that you have read, understood, and agree to Synth's <a href="https://synth.finance/terms" class="text-caribbean-green-500">Terms & Conditions</a> and <a href="https://synth.finance/privacy" class="text-caribbean-green-500">Privacy Policy</a>.
</div>
</div>
</div>
24 changes: 12 additions & 12 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<!DOCTYPE html>
<html class="h-full bg-gray-50">
<head>
<title><%= content_for?(:title) ? ("#{yield(:title)} - Maybe").html_safe : "Maybe" %></title>
<title><%= content_for?(:title) ? ("#{yield(:title)} - Synth").html_safe : "Synth" %></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

<meta name="title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Maybe").html_safe : "Maybe" %>">
<meta name="title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Synth").html_safe : "Synth" %>">
<meta name="description" content="<%= content_for?(:description) ? (yield(:description)) : "Fintech tools" %>">

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Maybe").html_safe : "Maybe" %>">
<meta property="og:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Synth").html_safe : "Synth" %>">
<meta property="og:description" content="<%= content_for?(:description) ? (yield(:description)) : "Fintech tools" %>">

<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Maybe").html_safe : "Maybe" %>">
<meta name="twitter:site" content="@maybe">
<meta name="twitter:creator" content="@maybe">
<meta name="twitter:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Synth").html_safe : "Synth" %>">
<meta name="twitter:site" content="@synthfinance">
<meta name="twitter:creator" content="@synthfinance">
<meta name="twitter:description" content="<%= content_for?(:description) ? (yield(:description)) : "Fintech tools" %>">

<%= csrf_meta_tags %>
Expand Down Expand Up @@ -48,20 +48,20 @@
</div>

<div>
<!--

<div class="p-4 mb-2">
<div class="flex w-full p-3 align-middle bg-white rounded-lg shadow-sm">
<div class="flex justify-between w-full p-3 align-middle bg-white rounded-lg shadow-sm">
<div class="flex flex-col justify-center">
<span class="text-sm text-gray-400 uppercase">Credit left:</span>
<b class="text-xl font-semibold"><%#= number_to_currency(current_user.balance) %></b>
<span class="text-sm text-gray-400 uppercase">Credits</span>
<b class="text-xl font-semibold"><%= current_user.balance %></b>
</div>

<div class="flex items-center justify-end w-32">
<%#= link_to "Add credit", billing_credits_path(20), class: "btn-primary", data: { turbo: false } %>
<%= link_to "Add credit", "billing_credits_path(20)", class: "btn-primary", data: { turbo: false } %>
</div>
</div>
</div>
-->


<div class="p-4 pt-0">
<button class="flex-shrink-0 block w-full rounded-xl group" data-dropdown-toggle="dropdownDotsHorizontal" data-dropdown-placement="top" data-dropdown-offset-skidding="">
Expand Down
14 changes: 7 additions & 7 deletions app/views/layouts/devise.html.erb
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<!DOCTYPE html>
<html class="h-full bg-gray-50">
<head>
<title><%= content_for?(:title) ? ("#{yield(:title)} - Maybe").html_safe : "Maybe" %></title>
<title><%= content_for?(:title) ? ("#{yield(:title)} - Synth").html_safe : "Synth" %></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Maybe").html_safe : "Maybe" %>">
<meta property="og:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Synth").html_safe : "Synth" %>">
<meta property="og:description" content="<%= content_for?(:description) ? (yield(:description)) : "" %>">

<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Maybe").html_safe : "Maybe" %>">
<meta name="twitter:site" content="@maybe">
<meta name="twitter:creator" content="@maybe">
<meta name="twitter:title" content="<%= content_for?(:title) ? ("#{yield(:title)} - Synth").html_safe : "Synth" %>">
<meta name="twitter:site" content="@synthfinance">
<meta name="twitter:creator" content="@synthfinance">
<meta name="twitter:description" content="<%= content_for?(:description) ? (yield(:description)) : "" %>">

<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
Expand All @@ -39,8 +39,8 @@
</div>

<div class="p-8 mt-2 text-sm text-center text-gray-400">
<p class="mt-6"><a href="https://maybe.co/privacy" class="text-gray-400">Privacy Policy</a> &bull; <a href="https://maybe.co/terms" class="text-gray-400">Terms of Service</a></p>
<p>&copy; 2023 Maybe. All rights reserved.</p>
<p class="mt-6"><a href="https://synth.finance/privacy" class="text-gray-400">Privacy Policy</a> &bull; <a href="https://synth.finance/terms" class="text-gray-400">Terms of Service</a></p>
<p>&copy; <%= Time.now.year %> Synth. All rights reserved.</p>
</div>
</div>
</body>
Expand Down
62 changes: 59 additions & 3 deletions app/views/pages/dashboard.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,59 @@
<div>
<h1 class="text-4xl font-bold">Dashboard</h1>
</div>
<div class="flex flex-col w-full max-w-3xl prose">
<h1 class="m-0 text-3xl font-medium">Overview</h1>

<h2 class="m-0 mt-3 text-2xl font-medium">Your API Key</h2>
<pre class="my-4 text-base"><code><%= current_user.api_keys.first.key %></code></pre>
<p class="mt-0 text-sm text-gray-500">Remember that your API key is a secret!. If someone gains access to your API key, they could potentially incur charges on your behalf.</p>
<!--
<h2 class="m-0 my-4 text-2xl font-medium">Pricing</h2>
<p class="text-sm font-normal text-gray-500 ">Pricing is based on usage. On a base level, we charge $0.000015 per character of content you send in for processing. That's obviously borderline useless for figuring out spending, though. 🙃</p>
<p class="m-0 text-sm font-normal text-gray-500 ">Basically, <b>it translates to about $0.75 per 10,000 words</b>.</p>
<p class="text-sm font-normal text-gray-500">Each API call you make will return the number of credits you used.</p>
<h2 class="m-0 my-4 text-2xl font-medium">Get to know the Detangle API</h2>
<div class="grid w-full grid-cols-2 gap-4">
<%= link_to 'https://docs.detangle.ai', class: 'flex space-x-2 no-underline border border-gray-200 hover:border-gray-300 rounded-xl p-3' do %>
<div class="text-2xl">👋</div>
<div>
<h3 class="m-0 text-base font-normal">Introduction</h3>
<p class="m-0 text-sm font-normal text-gray-500">Get started with the Detangle API</p>
</div>
<% end %>
<%= link_to 'https://docs.detangle.ai/reference/create-summarization', class: 'flex space-x-2 no-underline border border-gray-200 hover:border-gray-300 rounded-xl p-3' do %>
<div class="text-2xl">✍️</div>
<div>
<h3 class="m-0 text-base font-normal">Summarization</h3>
<p class="m-0 text-sm font-normal text-gray-500">Learn how to summarize files</p>
</div>
<% end %>
<%= link_to 'https://docs.detangle.ai/reference/create-extraction', class: 'flex space-x-2 no-underline border border-gray-200 hover:border-gray-300 rounded-xl p-3' do %>
<div class="text-2xl">🔍</div>
<div>
<h3 class="m-0 text-base font-normal">Extraction</h3>
<p class="m-0 text-sm font-normal text-gray-500">Pull any data from your documents</p>
</div>
<% end %>
<%= link_to 'https://docs.detangle.ai/reference/create-anonymization', class: 'flex space-x-2 no-underline border border-gray-200 hover:border-gray-300 rounded-xl p-3' do %>
<div class="text-2xl">🫥</div>
<div>
<h3 class="m-0 text-base font-normal">Anonymization</h3>
<p class="m-0 text-sm font-normal text-gray-500">Anonymize any sensitive data</p>
</div>
<% end %>
<%= link_to 'https://docs.detangle.ai/reference/create-sentiment-analysis', class: 'flex space-x-2 no-underline border border-gray-200 hover:border-gray-300 rounded-xl p-3' do %>
<div class="text-2xl">👍</div>
<div>
<h3 class="m-0 text-base font-normal">Sentiment Analysis</h3>
<p class="m-0 text-sm font-normal text-gray-500">Analyze the sentiment of any string of text</p>
</div>
<% end %>
<%= link_to 'https://zapier.com/developer/public-invite/190090/35f7dba89abf244e654914044b0c8cc3/', class: 'flex space-x-2 no-underline border border-gray-200 hover:border-gray-300 rounded-xl p-3 items-start' do %>
<%= image_tag('https://logo.clearbit.com/zapier.com', alt: 'Zapier Logo', class: 'm-0 mt-1 h-5 w-5') %>
<div>
<h3 class="m-0 text-base font-normal">Zapier</h3>
<p class="m-0 text-sm font-normal text-gray-500">Connect to thousands of services using Zapier!</p>
</div>
<% end %>
</div>
-->
</div>
2 changes: 1 addition & 1 deletion config/initializers/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
config.mailer_sender = 'hello@maybe.co'
config.mailer_sender = 'hello@synth.finance'

# Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'
Expand Down
12 changes: 12 additions & 0 deletions db/migrate/20240108022343_create_api_keys.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreateApiKeys < ActiveRecord::Migration[7.2]
def change
create_table :api_keys, id: :uuid do |t|
t.references :user, null: false, foreign_key: true, type: :uuid
t.string :key

t.timestamps

t.index :key, unique: true
end
end
end
5 changes: 5 additions & 0 deletions db/migrate/20240108022628_add_balance_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddBalanceToUsers < ActiveRecord::Migration[7.2]
def change
add_column :users, :balance, :integer, default: 0
end
end
13 changes: 13 additions & 0 deletions db/migrate/20240108022707_create_transactions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class CreateTransactions < ActiveRecord::Migration[7.2]
def change
create_table :transactions, id: :uuid do |t|
t.references :user, null: false, foreign_key: true, type: :uuid
t.integer :amount
t.string :description
t.datetime :transaction_timestamp
t.references :transactable, polymorphic: true, null: true, type: :uuid

t.timestamps
end
end
end
27 changes: 26 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions test/fixtures/api_keys.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
user: one
key: MyString

two:
user: two
key: MyString
11 changes: 11 additions & 0 deletions test/fixtures/transactions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
user: one
amount: 9.99
description: MyString

two:
user: two
amount: 9.99
description: MyString
Loading

0 comments on commit 5b93e9e

Please sign in to comment.