License key / products

(see marketing-sales-planning.txt specs doc for specific reasoning behind this)

CASE FOR THIS WORK IN ROCKFISH IS:
https://rockfish.ayanova.com/default.htm#!/rfcaseEdit/3724

CURRENT WORKING STATUS:

2018-06-01
Rough framework is in place, can fetch a key and can request a key but nothing really connected at the Rockfish end.
Rockfish will need some ui and other code to handle it
Putting that off until closer to release as Rockfish will no doubt change before then anyway (also involves a lot of UI work I'm not into right now)





PROCESS

LICENSE BOOTSTRAPPING	
	- RAVEN when boots and doesn't find a db then inits license will ensure a GUID DBID value  is set in LICENSE TABLE
		- This is used to match individual databases to licenses and avoid problems with registration names being the only differentiator as in v7
		- Also this is the new fetch code
	- RAVEN Is unlicensed it should check for a new key on a shorter frequency loop rather than once a day?
		or, providing a button to trigger that should be enough really
		or when server starts it starts the GENERATE loop and checks for a key right away, so they can just reboot teh server if they want an immediate license check?
	

	- RAVEN DB is empty (of biz data) it's license locked and a User MUST DONE ONE OF THE FOLLOWING:
		
		1) Restore a RAVEN database and reboot the server

		EMPTY DB AND EXISTING LICENSED KEY IN RF If this DBID is already present in ROCKFISH as *licensed* and FETCHED previously then:	
			Form displays a message, at top about restoring with link to the manual for restoring db
			Rest of form is related to releasing a previously fetched key:				
				Has a FETCH button on it for forcing a fetch when they have requested it or know it's coming or whatever and below that
				A form to fill out to request it be released for re-fetch:								
						User must fill out form stating reason why and their contact info for verification
						The request is emailed to us via Rockfish
						We decide to release or not and can contact them etc to handle it
						We can release it for refetch and then it's all automatic once daily check (maybe more frequent when unlicensed?) or they can force it

		EMPTY DB AND DBID NOT IN ROCKFISH
			User gets a form for requesting a trial 			
				- by filling out a form in RAVEN (or using api tool)	
				- see "trial process" below for details	
			Form has fetch key button on it to force an immediate fetch
			FUTURE: form displays a purchase link they can go to and make purchase inside RF


TRIAL / ONBOARDING PROCESS
==========================

*** SEE client todo for more up to date of this ***

FOR USER: Install RAVEN, boot, go to client endpoint in browser, get prompted for first test of contact with ROCKFISH server, 
	once that is ok then get prompted to fill out a form to request a trial key or attempt to fetch a key already ready for them
	User fills out form providing registration name and email address, hits send, told to check email to confirm address then will receive a key after that.
	They are told they can only request a new trial by erasing all the data first

FOR CODE:
	- RAVEN user requests a trial key for an empty db by filling out a form in RAVEN (or using api tool)	
		- registration name, email address are required fields
		- This request is stored in the db because it may need to be re-sent later on subsequent erasure of biz data
		- RAVEN makes and stores internally into a new DB a DBID value which uniquely identifies *THAT* database installation	
		- RAVEN transmits the request details (with dbid value) to ROCKFISH 
		
	- ROCKFISH validates the request by verifying the email address provided is (is still) valid and by getting our approval after that.
		- Verifies email by sending an email with a special trial code they need to enter into the license page which indicates they received the message and the email address is valid.
		- When they successfully enter the trial code and it vets as good (just some simple checksum system, nothing fancy at all, just needs to be uniqueish and confirm valid, probably part of an epoch timestamp) 
		- If the code is good then the email is valid so the RAVEN server contacts an api route to confirm the code was entered properly which then triggers the rest of the ROCKFISH process
		- If the code is good then RAVEN starts a repeating job that will periodically check the ROCKFISH server for a license response
		- If the email is valid then it creates a trial request record for us to view and approve or not approve with cause entered as text which will be sent to the user (like don't use fake names or profanity or something similar)
			- This part we WILL automate in future but for now it's a good "fuse"
		- The DBID value is associated permanently with a SITE record in ROCKFISH 
			we can override this value in case of weird issue unforseen
				although ideally we should be able to just shut down a "site" and create another site for that user so we have continuity

	- We get a notification of a request sitting in ROCKFISH and we approve it or not
		- IF APPROVED:
			- ROCKFISH generates (or looks up if repeat) a customer record, flags it as a trial type customer with a created date (for later GDPR removal or turning into a real customer record)
			- (ROCKFSIH UI needs a grouping for trial customers for main customer list)
			- ROCKFISH stores the DBID value in the SITE record
			- ROCKFISH generates a valid TRIAL license DBID code is the temporary fetch code.  
			- ROCKFISH Ultimately should do this automatically unless we specifically flag something
			- CLIENT LICENSE PAGE UI if refreshed or auto refreshed or whatever it will do updates the status showing licensed trial and expiry date etc
		- IF NOT APPROVED 
			- ROCKFISH creates a not approved type of license with the fetch code so that the server will stop polling
			- CLIENT DISPLAYS the not approved message right in the UI with the rejected message
			- ROCKFISH sends and email to the user explaining that it's a fail and why
	- RAVEN knows a request has been sent and has a license job that checks to see if a license is available periodically 
		- ROCKFISH returns a "no-op" type response if there is no license (as minimal as possible for bandwidth purposes since it's polling regularly)
		- ROCKFISH returns a "FAIL" type response if there is a fail with reason code to display to user
			- RAVEN CANCELS the check for license job and removes the request
		- ROCKFISH returns a license key when available under the dbid fetch code
			- ROCKFISH tags the license as "FETCHED" = true so it can't be fetched twice
			- RAVEN CANCELS the check for license job and attempts to install the key in normal process and initialize


PURCHASE PROCESS 
================


FOR USER:
Assuming ShareIt system still in place:
Customer makes a purchase, (possibly through RAVEN in which case the DBID is sent with the url to ShareIt to be filled into the purchase page automatically)
Customer enters their DBID as instructed into a box on the purchase page.  The order is not valid without it and it's a required field.
customer can easily copy their DB ID from within RAVEN 

We get the order and it gets transferred to ROCKFISH, license key is generated and an automated email notification is sent to user instructing that the license is ready for "pickup".
User (who is OPS full or limited or BIZ full) goes into the license page in RAVEN UI and selects "Check for new license" at which point the server does the check passing the GUID along with the check, if new license then it installs and inits and informs user.
If it's a fail for some reason informs user and no change to current license.


FOR CODE:

- RAVEN needs a DBID route in licensing controller to return the DBID available to OPS full or read only OR BIZ full rights only.
- ROCKFISH needs a way to send a license key email to the customer automatically upon generation
- ROCKFISH needs a new key generation page with the new options on it


RENEWAL PROCESS
===============

FOR USER:
If perpetual: They get a renewal upcoming notice if yearly (!=ServiceMode) from ROCKFISH so they can update payment info or cancel, RAVEN will start a license check job immediately before expiry
If Service: they do nothing, it's understood that it will start to check automatically for a new key around the time of expiry of the old key until it receives a CANCELLED response or a key or a FAIL

FOR CODE:
See below, basically raven will check with rockfish automatically and handle any problems



"8" KEY FORMAT
=================
- JSON format
- secured with hash signature, only we can issue valid keys
- Features, All licenseable items (and some configuration features) are in a single "Features" collection scheduledusers, accounting "Service" (meaning it's rental), "Trial" meaning it's a trial etc.
	- "ServiceMode" feature which indicates the license is for renting not perpetual so that it can trigger more constant check for new licenses or offer rental specific features and functionality
	- "TrialMode" feature which indicates it's a trial so a different UI can be presented in some areas with sales links etc
	- Futureproof, can put anything in there
- LicenseExpiration date that applies to all features together as a group (no more individual expiry dates)
	- When the license expires it stops working.  NO read only mode, nothing works except some ops routes to install a new license, that's it
- MaintenanceExpiration date that applies to support and updates subscription for all features of that license (no individual feature support expiry)
	- Used by "check for updates" code to see if they are eligable for an update and to auto-update
- ID This field is critical and should contain the customer ID followed by the license ID, so for example 34-506987
	- THESE points here below for this item may be invalid if we go with DBID instead, but keeping as seems to make sense
	- This way we can verify with automated tools the customer requesting without sending an actual name in text and also that they have the latest key or not
	- RAVEN says "This is my key 34-506987" to ROCKFISH which replies with "Here is a newer key [key]" or "You are up to date" or "Revoked for reason: [non payment]"
	- (Test keys are all 00-serialid)
- DBID
	- This field is the unique DB id (GUID) of the database in use that is first generated by RAVEN when it first boots with an empty db
	- It is stored in the global settings of the database and is never erased once it is set
	- It is also used in conjunction with the ID field or possibly on it's own to be the fetch code
- RegTo: ALL TRIAL KEYS ARE REGISTERED TO SOMEONE NO SUCH THING AS TWO LICENSES IN CIRCULATION WITH THE SAME NAME (i.e. no more "Unregistered trial" meaning it's a trial, every user will have a specific name to test it out)
	- Rockfish will issue a trial key upon first request from empty db
	- An empty regto is an invalid key.
- LicenseFormat
	- there will be a LicenseFormat version field which will be initially "8"
	- This is for future changes to how license is formatted to ease the code burden of detecting that
	- Old future release versions should work with new licenses but not the reverse



ROCKFISH CODE
- FETCHROUTE: Needs a route to automatically check for presence of new licenses from RAVEN, fetch and install them
	- Will return either a license or an object indicating error or nothing new to return


- UI: Needs a whole lot of ui and code to support 
	- automatic generation of license key from manual and future automated billing
	- Key stored and served when required with challenge and response system by past key id and customer number maybe
	automatic billing and renewals but initially generate licenses automatically based on payment info and all that shit

RAVEN CODE
- Raven if an empty db can send a request for a key to Rockfish with a registered name
- If db empty on boot set a Guid value in the global settings table that uniquely and permanently identifies that database
- RAVEN will have two addresses for fetching a license key to different domains so that we can stay up in case of an issue
	- i.e. it will try rockfish.AyaNova.com first but if it fails then fallback to rockfish.helloayanova.com as secondary
- If there is an existing key RAVEN will automatically check for a new key close to the expiry period of the old key
	- If a FAIL is returned it will stop checking and tell the user at which point they must manually start the check after fixing the issue
	- If a NOOP is returned it will reschedule to check again later
	- If a CANCELLED is returned then the customer is no longer active and it will never check again unless user manually forces a one time check and the license changes
	- If a license is returned RAVEN will attempt to install it and also clear the running check job and also clear the CANCELLED status

- RAVEN LICENSE OBJECT / TABLE add a DBID guid column 
- RAVEN LICENSE OBJECT / TABLE add a LastFetchStatus column corresponding to an enum of FAIL, ACTIVE, CANCELLED
- RAVEN LICENSE OBJECT / TABLE add a LastFetchMessage column with the last message from the ROCKFISH license route server (so FAIL can be stored and communicated to user)


USAGE:

- MUST be able to support monthly billing cycle (automatic license installation or approval so user doesn't have to install key every month)
	- Rockfish should have a licensed yay or nay or new available route for RAVEN to check periodically and also users can trigger a force check
- RAVEN checks periodically for new license to fetch in line with billing cycle or expiry cycle.
	- SAFE fallback if can't contact license server and allow a few misses before something kicks in, but not to allow people to use unlimited by blocking rockfish for example









PRODUCT LICENSE CHANGES FROM v7


Still optional and purchased separately:
QBOI, QBI, PTI

Possible idea: sold as "Accounting add on" and the user can use one of those of their choice and can switch which means 1 product instead of three which might make keys easier.
	Possible downside is that we can't track who uses what or what we sell how much of so puts a kink in marketing or planning for deprecation or where to spend 
	effort, however there are other ways of addressing that.


//INCLUDED ADD-ON's
OLI - INCLUDED / TURNED INTO GENERIC FEATURE IMPORT / EXPORT CONTACTS and SCHEDULE TO ICAL 
OutLookScheduleExport - INCLUDED / TURNED INTO GENERIC SCHED EXPORT ICAL FORMAT
Export to xls - Included with RAVEN
QuickNotification - Included with RAVEN
ImportExportDuplicate - Included with RAVEN
RI/WBI/MBI - UNNECESSARY with RAVEN


This all brings up the matter then that we might only have two things to license: the number of users and whether there is accounting or not.
	?? PROS and CONS INLINE WITH RAVEN DESIGN GOALS ??




THOUGHTS
Raven license key system specs:


- CONSIDER supporting non-connected scenario where user is not internet connected







???
- Don't worry about obfuscation at first (maybe ever, I mean, really)
- Need automated routine that checks with rockfish to fetch a license automatically when necessary
	- I.E. it's sub runs out so it starts checking if there is a newer license available and if so fetches it
- Need an alternative route and UI in Rockfish for RAVEN style license handling
- Must use a different signing key than AyaNova 7 so we don't expose v8 key stuff, (although, it's just the public part of the key to validate right?)
=====================================

RESEARCH SOURCES
- http://www.reprisesoftware.com/blog/2017/08/implement-a-recurring-revenue-license-model/
- https://www.linkedin.com/pulse/20140819084845-458042-the-change-from-perpetual-to-subscription-based-software-licensing
- http://software-monetization.tmcnet.com/articles/429528-long-but-rewarding-road-a-recurring-revenue-model.htm
- How to calculate pricing in a service business: https://www.patriotsoftware.com/accounting/training/blog/how-pricing-services-strategies-models-formula/
- SAAS pricing models: https://www.cobloom.com/blog/saas-pricing-models